有人告诉我在这里使用 AsyncTask:nullpointerexception-when-scrolling-fast 这就是我所做的,但我仍然遇到同样的错误:它工作正常,直到我开始快速滚动。当滚动非常慢时,不会发生此错误。这真的让我很困惑。
package com.mamlambo.tutorial.tutlist;
import java.util.ArrayList;
import java.util.TreeSet;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ImageView;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class TutListActivity extends Activity {
private DatabaseManager mHelper;
private SQLiteDatabase mDatenbank;
private ArrayList<String> devicesList;
ListView listView;
EfficientAdapter objectAdapter;
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Bitmap mIcon1;
private Bitmap mIcon2;
private TreeSet mSeparatorsSet = new TreeSet();
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
public EfficientAdapter(Context context) {
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
// Icons bound to the rows.
mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
}
public int getCount() {
return devicesList.size();
}
public void addItem(final String item) {
devicesList.add(item);
notifyDataSetChanged();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
@Override
public void notifyDataSetChanged() // Create this function in your adapter class
{
super.notifyDataSetChanged();
}
public void addSeparatorItem(final String item) {
devicesList.add(item);
// save separator position
mSeparatorsSet.add(devicesList.size() - 1);
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.list_item, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder.text = (TextView) convertView.findViewById(R.id.Title_List_Item);
holder.icon = (ImageView) convertView.findViewById(R.id.Delete_List_Item);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.seperator_item, null);
holder.text = (TextView)convertView.findViewById(R.id.Text_Seperator_Item);
break;
}
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
switch (type) {
case TYPE_ITEM:
convertView.findViewById(R.id.Title_List_Item).setTag(devicesList.get(position));
convertView.findViewById(R.id.Delete_List_Item).setTag(devicesList.get(position));
holder.text.setText(devicesList.get(position));
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
holder.text.setOnClickListener(mOnTitleClickListener);
holder.icon.setOnClickListener(mOnIconClickListener);
break;
case TYPE_SEPARATOR:
holder.text.setText(devicesList.get(position));
break;
}
return convertView;
}
private OnClickListener mOnTitleClickListener = new OnClickListener() {
public void onClick(View v) {
if(v.getTag().toString() == "ADD DEVICE"){
Intent addDevice = new Intent(getApplicationContext(), addDevice.class);
startActivity(addDevice);
}else{
Intent showRemote = new Intent(TutListActivity.this, Remote.class);
showRemote.putExtra("selectedDevice", v.getTag().toString());
startActivity(showRemote);
}
}
};
private OnClickListener mOnIconClickListener = new OnClickListener() {
public void onClick(View v) {
String NameOfDevice[] = new String[2];
NameOfDevice = v.getTag().toString().split(",");
mDatenbank.execSQL("DELETE FROM addedDevices WHERE name = '"+NameOfDevice[0]+"'");
ladeDevices();
objectAdapter.notifyDataSetChanged();
}
};
class ViewHolder {
TextView text;
ImageView icon;
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
mHelper = new DatabaseManager(this);
mDatenbank = mHelper.getReadableDatabase();
listView = (ListView) findViewById(R.id.list);
objectAdapter = new EfficientAdapter(this);
new LoadDevices().execute();
}
private class LoadDevices extends AsyncTask<String, Integer, String> {
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(String... params) {
devicesList = new ArrayList<String>();
Cursor devicesCursor = mDatenbank.query("addedDevices", new String[] {"name", "hersteller"}, null, null, null, null, null);
startManagingCursor(devicesCursor);
devicesCursor.moveToFirst();
for (int i=0;i<devicesCursor.getCount();i++){
String addingElement = new String(devicesCursor.getString(0)+", "+devicesCursor.getString(1));
objectAdapter.addItem(addingElement);
devicesCursor.moveToNext();
if (i % 4 == 0) {
objectAdapter.addSeparatorItem("separator " + i);
}
}
objectAdapter.addItem("ADD DEVICE");
return "All Done!";
}
@Override
protected void onProgressUpdate(Integer... values) {
}
@Override
protected void onPostExecute(String result) {
listView.setAdapter(objectAdapter);
}
}
private void ladeDevices() {
}
}
这是 Logcat 输出:
12-10 21:46:04.891: E/AndroidRuntime(5815): FATAL EXCEPTION: main
12-10 21:46:04.891: E/AndroidRuntime(5815): java.lang.NullPointerException
12-10 21:46:04.891: E/AndroidRuntime(5815): at com.mamlambo.tutorial.tutlist.TutListActivity$EfficientAdapter.getView(TutListActivity.java:152)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.widget.AbsListView.obtainView(AbsListView.java:2255)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.widget.ListView.makeAndAddView(ListView.java:1769)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.widget.ListView.fillDown(ListView.java:672)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.widget.ListView.fillGap(ListView.java:636)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5040)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3197)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3471)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.View.dispatchTouchEvent(View.java:7127)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2170)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1905)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
12-10 21:46:04.891: E/AndroidRuntime(5815): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1925)
12-10 21:46:04.891: E/AndroidRuntime(5815): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
12-10 21:46:04.891: E/AndroidRuntime(5815): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.View.dispatchPointerEvent(View.java:7307)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3174)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3119)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4155)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4134)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4226)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4205)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4245)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.Choreographer.doFrame(Choreographer.java:523)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.os.Handler.handleCallback(Handler.java:615)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.os.Handler.dispatchMessage(Handler.java:92)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.os.Looper.loop(Looper.java:137)
12-10 21:46:04.891: E/AndroidRuntime(5815): at android.app.ActivityThread.main(ActivityThread.java:4745)
12-10 21:46:04.891: E/AndroidRuntime(5815): at java.lang.reflect.Method.invokeNative(Native Method)
12-10 21:46:04.891: E/AndroidRuntime(5815): at java.lang.reflect.Method.invoke(Method.java:511)
12-10 21:46:04.891: E/AndroidRuntime(5815): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-10 21:46:04.891: E/AndroidRuntime(5815): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-10 21:46:04.891: E/AndroidRuntime(5815): at dalvik.system.NativeStart.main(Native Method)