0

今朝は頭がおかしくなりました。やりたいことをする方法が見つかりませんでした。私はAndroid APIが初めてです。

私が注意しているのは、データベースによってトリガーされたアダプターから ListView を更新することです。リストビューを作成するアクティビティを作成し、カスタム オブジェクト (AP) によって構築された配列リストを適応させるカスタム アダプター (BaseAdapter の子) を設定します。2 秒ごとにデータベースをスキャンしてデータベースからデータを取得する AsynchTask を起動し、arraylist を更新します (オブジェクトが存在しない場合は追加します)。doInBackground() メソッド publisProgress() を呼び出して、Google API で指定されている onProgressUpdate メソッドをトリガーします。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'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

自分のことを正しく行う方法を教えてください。良い方向に進んでいるかどうかは本当にわかりません。

どうもありがとうございます。

4

1 に答える 1

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() ;
                        }
                    }
                });
于 2013-08-26T12:38:42.417 に答える