Asynctask AdapterBase PublishProgress不起作用(应用程序搞砸了)

时间:2013-08-26 12:28:21

标签: android listview android-asynctask android-adapter

今天早上我心烦意乱,我找不到办法去做我想做的事。 我是Android API的新手。

我要做的是从数据库触发的适配器更新ListView。 我创建了我的Activity,在其中创建了我的listview并在其上设置了我的自定义适配器(BaseAdapter的子节点),它适应我的海关对象(AP)构建的arraylist。我想要一个AsynchTask,它将每2秒扫描一次我的数据库以从中获取数据,更新我的arraylist(添加一个对象,如果它不存在)。 我调用doInBackground()方法publisProgress()来触发google API上指定的onProgressUpdate方法。 当我调用publishProgress()时,我的问题就出现了。 我认为原因是我的asynchTask尝试访问UI对象,而在Android(adapter.notifyDatasetUpdate)上则不可能。 我不知道如何解决它。

我的代码:

Activity.java

public class MainActivity extends Activity {



ListView list ;
AdapterAP adapter ; 
ArrayList<AP> listAp ;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);      
    listAp = new ArrayList<AP>() ;
    list = (ListView) findViewById(R.id.list) ; 
    adapter = new AdapterAP(this, listAp) ; 
    Db_th db_th = new Db_th(listAp, this,adapter) ;
    list.setAdapter(adapter) ; 
    db_th.execute(listAp) ;
 }

}

Db_th.java

public class Db_th extends AsyncTask<ArrayList<AP>, Void, String>{

    @Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    Toast.makeText(context, result, Toast.LENGTH_LONG).show() ; 
}

ArrayList<AP> listAp= new ArrayList<AP>();  
Context context ; 
Activity activity ;
AdapterAP adapter; 

public Db_th (ArrayList<AP> listAp, Context context , AdapterAP adapter) {
    super() ;
    this.listAp = listAp ; 
    this.context = context ;
    //this.adapter = adapter ; 
    this.adapter = adapter ; 
}



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



@Override
protected String doInBackground(ArrayList<AP>... params) {

    //String ret = new String() ; 
    SQLiteDatabase db = SQLiteDatabase.openDatabase("/data/local/tmp/sniffer.db", null, SQLiteDatabase.OPEN_READONLY) ;
    String get_ap = new String("SELECT * from ssid") ;
    String count_ap = new String("SELECT COUNT(id) FROM ssid WHERE name=") ; 
    Cursor cursor ;
    while (true) {
        cursor = db.rawQuery(get_ap, null) ; 
        cursor.moveToFirst() ; 
        while (!cursor.isAfterLast()) {
            if (!search_id(cursor.getInt(0)))
                listAp.add(new AP(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getInt(3), cursor.getFloat(4), cursor.getInt(5), null, null)) ; // NO PROBLEM WITH PASSING NULL
            cursor.moveToNext() ; 
        }
        publishProgress(null) ;
        try {
            Thread.sleep(2) ;
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }

}


@Override
protected void onProgressUpdate(Void... values) {
    //super.onProgressUpdate(values); COMMENT HERE BECAUSE I READ THAT COULD SCREW UP APK 
    adapter.notifyDataSetChanged() ;
}

protected boolean search_id(int id) {

    for (AP ap : listAp) {
        if (ap.getId() == id) 
            return true ; 
    }
    return false;
}

 }

AdapterAP.java

public class AdapterAP extends BaseAdapter{

static class ViewHolder {
      // MY FIELDS
}

private Activity activity ; 
private ArrayList<AP> listAp ; 
private static LayoutInflater layoutInflat ; 

public AdapterAP(Activity activity, ArrayList<AP> listAp) {
    this.activity = activity ; 
    this.listAp = listAp ; 
    layoutInflat = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE) ; 
}

@Override
public int getCount() {
    return listAp.size() ; 
}

@Override
public Object getItem(int arg0) {
    return listAp.get(arg0);
}

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

@Override
public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder ; 
    if (convertView == null) {
        convertView = layoutInflat.inflate(R.layout.row_ap, null) ; 

        // holder.creatingmyview

        convertView.getTag() ; 
    } else {
        holder = (ViewHolder) convertView.getTag() ; 
    }

    //holder.doingmystuff


    return convertView;
}

}

当然我甚至试图将我的asynctask'constructor传递给视图并制作一个

(BaseAdapter)((ListView)list.getAdapter()) 

但它没有任何改变,因为它总是引用UI元素(实际上是相同的)。 我接受了一个可以来自publishProgress(void)的NullPointerExecption,但我不明白为什么。

LogCat:

08-26 07:58:10.614: E/AndroidRuntime(2149): FATAL EXCEPTION: main
08-26 07:58:10.614: E/AndroidRuntime(2149): java.lang.NullPointerException
08-26 07:58:10.614: E/AndroidRuntime(2149):         at com.example.wisniffer.Db_th.onProgressUpdate(Db_th.java:80)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at com.example.wisniffer.Db_th.onProgressUpdate(Db_th.java:1)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:647)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at android.os.Handler.dispatchMessage(Handler.java:99)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at android.os.Looper.loop(Looper.java:137)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at android.app.ActivityThread.main(ActivityThread.java:5103)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at java.lang.reflect.Method.invokeNative(Native Method)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at java.lang.reflect.Method.invoke(Method.java:525)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-26 07:58:10.614: E/AndroidRuntime(2149):         at dalvik.system.NativeStart.main(Native Method)
08-26 07:58:12.924: I/Process(2149): Sending signal. PID: 2149 SIG: 9

请教我如何正确地做我的东西,我真的不知道我是否朝着好的方向发展。

非常感谢你。

1 个答案:

答案 0 :(得分:1)

请这样:

onProgressUpdate()方法

中删除此行
adapter.notifyDataSetChanged() ;

并覆盖 onPostExecute()方法并将此行添加到其中:

@Override
            protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
                super.onPostExecute(result);
              adapter.notifyDataSetChanged() ;
            }

<强>更新

runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        if(adapter!=null){
                            adapter.notifyDataSetChanged() ;
                        }
                    }
                });