в асинхронной задаче: попытка вызвать виртуальный метод ‘ void android.штучка.элемент управления ListView.setAdapter (android.штучка.ListAdapter) ‘ для ссылки на нулевой объект

Чего я хочу

При нажатии на маркер на карте, показать диалоговое окно оповещения с видом списка (содержащий текст)

Ошибка LogCat

05-01 23:20:21.098 11392-11654/com.example.talha.atmlocaterproject W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$override.retreive_message(MainActivity.java:372)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$override.access$dispatch(MainActivity.java)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity.retreive_message(MainActivity.java:0)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$GetAtms.doInBackground(MainActivity.java:300)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$GetAtms.doInBackground(MainActivity.java:257)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at android.os.AsyncTask.call(AsyncTask.java:288)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at android.os.AsyncTask$SerialExecutor

What i want

When click on Marker in Map, Show alert dialog with list view (containing text)

LogCat Error

05-01 23:20:21.098 11392-11654/com.example.talha.atmlocaterproject W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$override.retreive_message(MainActivity.java:372)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$override.access$dispatch(MainActivity.java)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity.retreive_message(MainActivity.java:0)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$GetAtms.doInBackground(MainActivity.java:300)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at com.example.talha.atmlocaterproject.MainActivity$GetAtms.doInBackground(MainActivity.java:257)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err:     at java.lang.Thread.run(Thread.java:818)

What i am doing is in OnMarkerClick() is calling AsyncTask to get message from cloud.

@Override
public boolean onMarkerClick(Marker marker) {
    String atm_title = marker.getTitle();
    option = "retreive_message";
    new GetAtms(atm_title).execute();      //here is the call to asyncTask
    return false;
} 

Now in doInBackground() method , i retreive the message from cloud and set adapter

DBCollection c5  = db.getCollection("ATM_message");
    String[] atm_message = new String[50];
    try{
        Log.d("retreive message","before lopping");
        DBCursor cursor = c5.find();
        String atm_title,message,username;
        int message_adding_counter = 0;
        while (cursor.hasNext()) {
            DBObject doc = cursor.next();
            atm_title = "" + doc.get("atm_name");
            message = "" + doc.get("message");
            username ="" + doc.get("username");
            Log.d("retreive message","between lopping");

            if(atm_title.equalsIgnoreCase(title)){
                atm_message[message_adding_counter]=message;
                Log.d("retreive message"," adding message");

            }
        }
        Log.d("retreive message","" + atm_message[0]);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.list_item,R.id.textView,atm_message);
        listview.setAdapter(adapter);
        showDailogListView(listview);

showDailogListView()

public void showDailogListView(View view){
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setCancelable(true);
    builder.setPositiveButton("OK",null);
    builder.setView(view);
    AlertDialog dailog = builder.create();
    dailog.show();
}

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">


<TextView
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_text="New Text"
    android_padding="10dp"
    android_id="@+id/textView"
    android_layout_gravity="center_horizontal" />
</LinearLayout>

OnCreate()

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mProgressDialog= new ProgressDialog(this);

    try {
        MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

.run(AsyncTask.java:231)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-01 23:20:21.099 11392-11654/com.example.talha.atmlocaterproject W/System.err: at java.lang.Thread.run(Thread.java:818)

То, что я делаю, в OnMarkerClick() вызывает AsyncTask, чтобы получить сообщение из облака.

@Override
public boolean onMarkerClick(Marker marker) {
    String atm_title = marker.getTitle();
    option = "retreive_message";
    new GetAtms(atm_title).execute();      //here is the call to asyncTask
    return false;
} 

Теперь в методе doInBackground () я возвращаю сообщение из облака и устанавливаю адаптер

DBCollection c5  = db.getCollection("ATM_message");
    String[] atm_message = new String[50];
    try{
        Log.d("retreive message","before lopping");
        DBCursor cursor = c5.find();
        String atm_title,message,username;
        int message_adding_counter = 0;
        while (cursor.hasNext()) {
            DBObject doc = cursor.next();
            atm_title = "" + doc.get("atm_name");
            message = "" + doc.get("message");
            username ="" + doc.get("username");
            Log.d("retreive message","between lopping");

            if(atm_title.equalsIgnoreCase(title)){
                atm_message[message_adding_counter]=message;
                Log.d("retreive message"," adding message");

            }
        }
        Log.d("retreive message","" + atm_message[0]);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.list_item,R.id.textView,atm_message);
        listview.setAdapter(adapter);
        showDailogListView(listview);

showDailogListView()

public void showDailogListView(View view){
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setCancelable(true);
    builder.setPositiveButton("OK",null);
    builder.setView(view);
    AlertDialog dailog = builder.create();
    dailog.show();
}

элемент списка.XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">


<TextView
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_text="New Text"
    android_padding="10dp"
    android_id="@+id/textView"
    android_layout_gravity="center_horizontal" />
</LinearLayout>

OnCreate()

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mProgressDialog= new ProgressDialog(this);

    try {
        MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

3 ответа

  1. Лучший способ-вернуть адаптер массива из метода doInBackground и установить диалог хода выполнения в методе onPreExecute;

    doInBackground(){
    //your code
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.list_item,R.id.textView,atm_message);
    return adapter;
    }
    
    @Override
        protected void onPostExecute(ArrayAdapter<String> result) {
          return result;
        }
    

    //////////////

    public boolean onMarkerClick(Marker marker) {
        String atm_title = marker.getTitle();
        option = "retreive_message";
       ArrayAdapter<String> adapter=(new GetAtms(atm_title)).execute();      
       listview.setAdapter(adapter);
        return false;
    } 
    
  2. Попробуйте использовать onPostExecuteдля работы с вашим пользовательским интерфейсом:

    Изменение подписи AsyncTask:

    public class GetAtms extends AsyncTask<Void, Void, String[]> {
        private ArrayAdapter<String> mAdapter;
    
        public GetAtms(String title, ArrayAdapter<String> adapter)
        {
            mAdapter = adapter;
            //the rest of the constructor codes
        }
    
        //rest of your code
    

    пусть doInBackgroundвозвращается массив строки результата onPostExecute

    DBCollection c5  = db.getCollection("ATM_message");
    String[] atm_message = new String[50];
    try{
        Log.d("retreive message","before lopping");
        DBCursor cursor = c5.find();
        String atm_title,message,username;
        int message_adding_counter = 0;
        while (cursor.hasNext()) {
            DBObject doc = cursor.next();
            atm_title = "" + doc.get("atm_name");
            message = "" + doc.get("message");
            username ="" + doc.get("username");
            Log.d("retreive message","between lopping");
    
            if(atm_title.equalsIgnoreCase(title)){
                atm_message[message_adding_counter]=message;
                Log.d("retreive message"," adding message");
    
            }
        }
        Log.d("retreive message","" + atm_message[0]);
    
        return atm_message;
    

    in onPostExecutedo:

    public void onPostExecute(String[] data)
    {
        mAdapter.clear();
        mAdapter.addAll(data);
    }
    

    и, наконец, изменить onMarkerClick:

    public boolean onMarkerClick(Marker marker) {
        String atm_title = marker.getTitle();
        option = "retreive_message";
        ListView listview = (ListView) findViewById(...) //your listview resource
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.list_item,R.id.textView,null);
        listView.setAdapter(adapter);
        new GetAtms(atm_title,adapter).execute();      //here is the call to asyncTask
        return false;
    
    } 
    
  3. Если U сталкивается с нулевой ссылкой на объект, пожалуйста, сначала посмотрите ,что все textview правильно findViewById сделано, а во-вторых, какой бы адаптер вы ни устанавливали, пожалуйста, сделайте это в методе postexecute, он будет работать.