Hallo,
ich habe ein Problem das mich schon seit einigen Tagen ärgert und für das ich keine richtige Lösung finde:
Ich habe ein kleines Programm gebastelt, welches irgendwann mal zu einer Universalfernbedienung heranwachsen soll. Soweit habe ich eine Liste mit einem eigenen Listenadapter erstellt, welche verschiedene Kategorien und für jedes Element noch einen Löschen Button beinhalten soll. Die Liste zeigt verschiedene Geräte an, die mit der Fernbedienung bedient werden können. Die Daten welche angezeigt werden sollen sind in einer internen Datenbank gespeichert. Mit dem letzten Eintrag der Liste gelangt man zu einer neuen activity wo man aus einer online Datenbank neue Geräte in die Datenbank des Handys laden kann.
Soweit so gut. Es funktioniert ansich auch alles wie es soll, bis man anfängt etwas schneller zu scrollen. Dann stürzt das Programm nämlich ab und ich kann absolut nicht entdecken woran das liegen kann:
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 = new DatabaseManager(this);
private SQLiteDatabase mDatenbank;
private ArrayList<String> devicesList;
private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();
ListView listView;
EfficientAdapter objectAdapter;
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Bitmap mIcon1;
private Bitmap mIcon2;
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) {
mInflater = LayoutInflater.from(context);
mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
}
public int getCount() {
return devicesList.size();
}
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();
}
@Override
public int getItemViewType(int position) {
return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.list_item, null);
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 {
holder = (ViewHolder) convertView.getTag();
}
System.out.println(convertView);
System.out.println(devicesList);
System.out.println(position);
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);
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() {
mDatenbank = mHelper.getReadableDatabase();
}
@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));
devicesList.add(addingElement);
devicesCursor.moveToNext();
if (i % 4 == 0) {
devicesList.add("separator " + i);
mSeparatorsSet.add(devicesList.size() - 1);
}
}
devicesList.add("ADD DEVICE");
return "All Done!";
}
@Override
protected void onProgressUpdate(Integer... values) {
}
@Override
protected void onPostExecute(String result) {
listView.setAdapter(objectAdapter);
mDatenbank.close();
}
}
private void ladeDevices() {
}
}
Alles anzeigen
Ich habe die Datenbank abfrage schon in einen anderen thread ausgelagert, aber die Fehlermeldung bleibt die Gleiche:
01-09 16:27:42.415: D/AndroidRuntime(24083): Shutting down VM
01-09 16:27:42.415: W/dalvikvm(24083): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
01-09 16:27:42.536: E/AndroidRuntime(24083): FATAL EXCEPTION: main
01-09 16:27:42.536: E/AndroidRuntime(24083): java.lang.NullPointerException
01-09 16:27:42.536: E/AndroidRuntime(24083): at com.mamlambo.tutorial.tutlist.TutListActivity$EfficientAdapter.getView(TutListActivity.java:137)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.widget.AbsListView.obtainView(AbsListView.java:1428)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.widget.ListView.makeAndAddView(ListView.java:1801)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.widget.ListView.fillDown(ListView.java:671)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.widget.ListView.fillGap(ListView.java:642)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3452)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.widget.AbsListView.onTouchEvent(AbsListView.java:2256)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.widget.ListView.onTouchEvent(ListView.java:3502)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.View.dispatchTouchEvent(View.java:3933)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:955)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
01-09 16:27:42.536: E/AndroidRuntime(24083): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1877)
01-09 16:27:42.536: E/AndroidRuntime(24083): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1211)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.app.Activity.dispatchTouchEvent(Activity.java:2228)
01-09 16:27:42.536: E/AndroidRuntime(24083): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1852)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2382)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.view.ViewRoot.handleMessage(ViewRoot.java:2010)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.os.Handler.dispatchMessage(Handler.java:99)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.os.Looper.loop(Looper.java:150)
01-09 16:27:42.536: E/AndroidRuntime(24083): at android.app.ActivityThread.main(ActivityThread.java:4385)
01-09 16:27:42.536: E/AndroidRuntime(24083): at java.lang.reflect.Method.invokeNative(Native Method)
01-09 16:27:42.536: E/AndroidRuntime(24083): at java.lang.reflect.Method.invoke(Method.java:507)
01-09 16:27:42.536: E/AndroidRuntime(24083): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
01-09 16:27:42.536: E/AndroidRuntime(24083): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
01-09 16:27:42.536: E/AndroidRuntime(24083): at dalvik.system.NativeStart.main(Native Method)
Alles anzeigen
Line 137 ist folgende:
Allerdings wird weder convertView noch position oder devicesList zu null. Zudem bleibt der Fehler der gleiche, wenn ich die Zeile auskommentiere. Er zeigt dann nur auf die nächste Zeile.
Ich hoffe mir kann jemand helfen. Ich bin fast am verzweifeln...