今天早上我大吃一惊,我没有找到一种方法来做我想做的事。我是 Android API 的新手。
我要做的是从由数据库触发的适配器更新 ListView。我创建了我的 Activity,在其中创建了我的列表视图并在其上设置了我的自定义适配器(BaseAdapter 的子级),该适配器适应了由海关对象(AP)构建的我的数组列表。我启动了一个异步任务,它将每 2 秒扫描一次我的数据库以从中取回数据,更新我的数组列表(如果它不存在则添加一个对象)。我调用 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;
}
}
适配器AP.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,但我不明白为什么。
日志猫:
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
请教我如何正确地做我的事情,我真的不知道我是否朝着好的方向发展。
非常感谢你。