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



今天早上我疯了,我没有找到做我想做的事的方法。我是安卓API的新手。

我要做的是从数据库触发的适配器更新ListView。我创建了我的"活动",在其中我创建了列表视图,并在上面设置了我的自定义适配器(BaseAdapter的子级),以调整由自定义对象(AP)构建的数组列表。我启动了一个AsynchTask,它将每2秒扫描我的数据库以从中获取数据,并更新我的arraylist(如果上面不存在对象,则添加一个对象)。我调用doInBackground()方法publisProgress()来触发onProgressUpdate方法,如在google API上指定的。当我调用publishProgress()我的应用程序出错时,就会出现问题。我认为原因是我的asynchTask试图访问UI对象,而这在Android上是不可能的(adapter.notifyDatasetUpdate)。我不知道该怎么修。

我的代码:

活动.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构造函数,并制作一个

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

但它什么也不改变,因为它总是引用一个UI元素(事实上也是如此)。我接受了一个可以来自publishProgress(void)的NullPointerExection,但我不明白为什么。

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

请教我如何正确地做我的事情,我真的不知道我是否朝着好的方向前进。

非常感谢。

这样做:

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() ;
                        }
                    }
                });

相关内容

  • 没有找到相关文章

最新更新