在异步任务中:尝试在空对象引用上调用虚拟方法 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)'
in Async Task : Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
我想要什么
点击地图中的标记时,显示带有列表视图的警告对话框(包含文本)
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.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();
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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();
}
}
更好的方法是从 doInBackground 方法 return 阵列适配器并在 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;
}
尝试用onPostExecute
对付你的UI:
更改 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
return结果String数组到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;
在onPostExecute
中做:
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;
}
如果您面临空对象引用,请首先查看所有 textview 是否已正确完成 findviewbyid,其次,无论您设置的是什么适配器,请在执行后方法中进行操作,它会起作用,请尝试一下。
我想要什么
点击地图中的标记时,显示带有列表视图的警告对话框(包含文本)
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.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();
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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();
}
}
更好的方法是从 doInBackground 方法 return 阵列适配器并在 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;
}
尝试用onPostExecute
对付你的UI:
更改 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
return结果String数组到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;
在onPostExecute
中做:
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;
}
如果您面临空对象引用,请首先查看所有 textview 是否已正确完成 findviewbyid,其次,无论您设置的是什么适配器,请在执行后方法中进行操作,它会起作用,请尝试一下。