2017-01-03 4 views
1

ich eine Liste von Links zu machen und für die ich habe einen eigenen Adapter hergestellt, aber die Liste ist nicht bereit, wenn der Adapter startet, damit ich die folgende Fehlermeldung erhalten:Individuelle Adapter beginnen, bevor Arraylist ist bereit

java.lang.RuntimeException: Unable to start activity ComponentInfo{}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference

dies liegt daran, dass, wenn der Adapter die Liste leer ist, und nur wenig Minuten nach der Liste gefüllt sind gestartet, aber es ist zu spät, hier ist mein Code:

UPDATE: der Code so jetzt geändert worden ist ich mich nicht Holen Sie sich den Fehler, aber es führt nicht getView im Adapter:

public class Controller extends Activity { 

private String TAG = Controller.class.getSimpleName(); 
private String http; 
CustomAdapter adapter; 
public Controller con = null; 
private ListView lv; 
private static String url; 
ArrayList<Selfservice> linkList = new ArrayList<Selfservice>(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main_view); 
    con = this; 
    http = this.getString(R.string.http); 
    url = this.getString(R.string.path1); 

    new GetLinks().execute(); 

    lv = (ListView)findViewById(R.id.list); 

    //Resources res = getResources(); 
    //adapter = new CustomAdapter(con, linkList, res); 
    //lv.setAdapter(adapter); 
} 

private class GetLinks extends AsyncTask<Void, Void, List<Selfservice>> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

    } 

    @Override 
    protected List<Selfservice> doInBackground(Void... arg0) { 
       Document doc; 
       Elements links; 
       List<Selfservice> returnList = null; 
       try { 
        doc = Jsoup.connect(url).timeout(0).get(); 
        links = doc.getElementsByClass("processlink"); 
        returnList = ParseHTML(links); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

     return returnList; 
    } 

    @Override 
    protected void onPostExecute(final List<Selfservice> result) { 
     super.onPostExecute(result); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
       //setSupportActionBar(toolbar); 
       //getSupportActionBar().setDisplayShowTitleEnabled(false); 
       toolbar.setTitle(""); 
       toolbar.setSubtitle(""); 
       Resources res = getResources(); 
       Log.e(TAG, linkList.toString()); 
       linkList = (ArrayList<Selfservice>) result; 
       adapter = new CustomAdapter(con, result, res); 
       adapter.notifyDataSetChanged(); 
       lv.setAdapter(adapter); 
      } 
     }); 

    } 

} 

und mein Adapter:

public class CustomAdapter extends BaseAdapter implements OnClickListener { 
private String TAG = CustomAdapter.class.getSimpleName(); 
Context context; 
List<Selfservice> data; 
private Activity activity; 
public Resources res; 
Selfservice self = null; 
private static LayoutInflater inflater; 
int layoutResourceId = 0; 

public CustomAdapter(Activity act, List<Selfservice> dataList, Resources resources) { 

    res = resources; 
    activity = act; 
    data = dataList; 

} 

private class Holder { 
    TextView title; 
    TextView link; 
} 

@Override 
public int getCount() { 

    return data.size(); 
} 

@Override 
public Object getItem(int pos) { 
    return pos; 
} 

@Override 
public long getItemId(int pos) { 
    return pos; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View rowView = convertView; 
    Holder holder; 

    if(rowView == null){ 


     rowView = inflater.inflate(R.layout.list_item, null); 
     holder = new Holder(); 
     holder.title = (TextView) rowView.findViewById(R.id.title); 
     holder.link = (TextView) rowView.findViewById(R.id.link); 

     rowView.setTag(holder); 


    }else{ 
     holder = (Holder)rowView.getTag(); 
    } 
    if(data.size()<=0){ 
     holder.title.setText("did not work"); 
    }else{ 
     self = null; 
     self = (Selfservice) data.get(position); 
     holder.title.setText(self.getTitle()); 
     holder.link.setText(self.getLink()); 
     Log.i(TAG, "adapter"); 
     rowView.setOnClickListener(new OnItemClickListener(position)); 
    } 

    return rowView; 
    } 
@Override 
public void onClick(View v){ 
    Log.v("CustomAdapter", "row clicked"); 
} 

private class OnItemClickListener implements OnClickListener{ 
    private int mPos; 

    OnItemClickListener(int position){ 
     mPos = position; 
    } 
    @Override 
    public void onClick(View arg0){ 
     Controller con = (Controller)activity; 
     con.onItemClick(mPos); 
    } 
    } 
} 

So Wie erhalte ich den Adapter zu warten, um die Liste voll ist?

+0

Erstellen Sie nicht Adapter in der OnCreate-Methode. Sie müssen den Adapter nur erstellen, wenn Ihre asynchrone Aufgabe ein Ergebnis hat. Überprüfen Sie meine Antwort für den Code. –

Antwort

0

Sie können den Adapter in onPostExecute erstellen;

Ändern der Async Aufgabe dazu:

private class GetLinks extends AsyncTask<Void, Void, List<Selfservice>> { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

     } 

     @Override 
     protected Void doInBackground(Void... arg0) { 
        Document doc; 
        Elements links; 
        List<Selfservice> returnList 

        try { 
         doc = Jsoup.connect(url).timeout(10000).get(); 
         links = doc.getElementsByClass("processlink"); 
         returnList = ParseHTML(links); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

      return returnList; 
     } 

     @Override 
     protected void onPostExecute(List<Selfservice> result) { 
      super.onPostExecute(result); 
      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
        //setSupportActionBar(toolbar); 
        //getSupportActionBar().setDisplayShowTitleEnabled(false); 
        toolbar.setTitle(""); 
        toolbar.setSubtitle(""); 

        linkList = result 
        adapter = new CustomAdapter(con, result, res); 
        lv.setAdapter(adapter); 
       } 
      }); 

     } 

diese Weise werden Sie nur den Adapter erstellen, wenn Ihre Liste fertig ist.

Edit: Sie sind nicht die Variable Kontext in Ihrem Adapter zu schaffen. Ändern Sie Ihren Konstruktor diese:

public CustomAdapter(Context context, Activity act, List<Selfservice> dataList, Resources resources) { 

    res = resources; 
    activity = act; 
    data = dataList; 
    this.context = context; 

} 

Und Sie werden aufhören zu sehen, die NullPointerExecption

+0

Das hat fast funktioniert Ich kann sehen, dass die Liste aktualisiert wird, bevor der Adapter gestartet wird, aber mein Adapter funktioniert nicht, es führt nicht getView und dann wird nichts auf der App angezeigt :-( – TWOcvfan

+0

Bitte bearbeiten Sie Ihre Frage und zeigen Sie, wie Ihr Code ist gerade jetzt, damit ich Ihnen besser helfen kann. Haben Sie die Adaptererstellung in der onCreate-Methode entfernt? –

+0

Okay, ich habe den Code aktualisiert, und ja, ich habe die Adaptererstellung in der OnCreate-Methode entfernt – TWOcvfan

1

zunächst ArrayAdapter<Selfservice> anstelle von BaseAdapter

Verwendung Konstruktor

public CustomAdapter(Context context, int resource, List<Selfservice> objects) { 
    super(context, resource, objects); 
    data = objects; 
} 

dann außer Kraft setzen nur zwei Methoden

public int getCount()

public View getView(int position, View convertView, ViewGroup parent)

dann return list.size() in getCount()

in getView() Methode

if (convertView == null) { 
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    v = inflater.inflate(R.layout.list_item, null); 
} 

in doInBackground() Methode im try-Block anstelle von linkList = ParseHTML(links); tun linkList.addAll(ParseHTML(links));

und in onPostExcecute() Methode adapter.notifyDatasetChanged(); im ui-Thread

+0

Dies funktioniert nicht, LayooutInflater und linkList.addAll (ParseHTML (links)); gibt mir ein nullpointerexption – TWOcvfan

+0

nach dem Update sollten Sie @Override public int getCount() { return data.size(); } –

Verwandte Themen