ORIGINAL TITLE:在AsyncTask中使用MongoDB游标的android.os.NetworkOnMainThreadException?
我正在使用AndroidStudio和MongoDB后端为Android开发,尽管使用AsyncTask执行与网络相关的所有操作,但我得到了NetworkOnMainThreadException。
这是我们的数据库类(MyDB)中调用GetTasksTask(AsyncTask的子类)的方法:
public void getStoredTasks(CallbackHandler<ArrayList<PAWTask>> handler) {
GetTasksTask task = new GetTasksTask(mongoDB, handler);
task.doInBackground();
}
这里是GetTasksTask类(PAWTaskMongo是一个Mongo模型类,PAWTask是整个应用程序中使用的包装器):
private class GetTasksTask extends AsyncTask<Void, Void, ArrayList<PAWTask>> {
private DB mongoDB;
private CallbackHandler handler;
public GetTasksTask(DB mongoDB, CallbackHandler handler) {
this.mongoDB = mongoDB;
this.handler = handler;
}
@Override
protected ArrayList<PAWTask> doInBackground(Void... voids) {
ArrayList<PAWTask> storedTasks = new ArrayList<PAWTask>();
DBCollection coll = mongoDB.getCollection(DBMongoParse.PAW_TASK_COLLECTION);
BasicDBObject query = new BasicDBObject("isDeleted", false);
List<DBObject> tasks = coll.find(query).toArray();
for (DBObject task : tasks) {
storedTasks.add(new PAWTask((PAWTaskMongo) task));
}
return storedTasks;
}
@Override
protected void onPostExecute(ArrayList<PAWTask> result) {
handler.handle(result);
}
}
CallbackHandler的代码:
public abstract class CallbackHandler<T> {
public abstract void handle(T result);
}
以下是我如何获取Mongo DB的实例(在我实例化MyDB类时,之前已完成):
private MyDB() {
new OpenMongoConnectionTask().execute();
}
private class OpenMongoConnectionTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... voids) {
try {
MongoClient mongoClient = new MongoClient();
mongoDB = mongoClient.getDB("mydb");
pawTaskCollection = mongoDB.getCollection(PAW_TASK_COLLECTION);
pawTaskCompleteCollection = mongoDB.getCollection(PAW_TASK_COMPLETE_COLLECTION);
} catch (UnknownHostException e) {
e.printStackTrace();
}
return null;
}
}
这是我得到的异常(它会被抛出AsyncTask中的coll.find(query);
行:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mudd.heatlab.pawpal/com.mudd.heatlab.pawpal.tasklist.TaskListActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5102)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getByName(InetAddress.java:289)
at com.mongodb.ServerAddress.getSocketAddress(ServerAddress.java:185)
at com.mongodb.DBPort.ensureOpen(DBPort.java:255)
at com.mongodb.DBPort.<init>(DBPort.java:89)
at com.mongodb.DBPortFactory.create(DBPortFactory.java:28)
at com.mongodb.PooledConnectionProvider$ConnectionItemFactory.create(PooledConnectionProvider.java:186)
at com.mongodb.PooledConnectionProvider$ConnectionItemFactory.create(PooledConnectionProvider.java:183)
at com.mongodb.ConcurrentPool.createNewAndReleasePermitIfFailure(ConcurrentPool.java:150)
at com.mongodb.ConcurrentPool.get(ConcurrentPool.java:118)
at com.mongodb.PooledConnectionProvider.get(PooledConnectionProvider.java:75)
at com.mongodb.DefaultServer.getConnection(DefaultServer.java:60)
at com.mongodb.BaseCluster$WrappedServer.getConnection(BaseCluster.java:216)
at com.mongodb.DBTCPConnector$MyPort.getConnection(DBTCPConnector.java:503)
at com.mongodb.DBTCPConnector$MyPort.get(DBTCPConnector.java:451)
at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:286)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:271)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:84)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:66)
at com.mongodb.DBCursor._check(DBCursor.java:458)
at com.mongodb.DBCursor._hasNext(DBCursor.java:546)
at com.mongodb.DBCursor._fill(DBCursor.java:605)
at com.mongodb.DBCursor.toArray(DBCursor.java:640)
at com.mongodb.DBCursor.toArray(DBCursor.java:629)
at com.mudd.heatlab.pawpal.dbonline.GetTasksTask.doInBackground(GetTasksTask.java:32)
at com.mudd.heatlab.pawpal.dbonline.DBMongoParse.getStoredTasks(DBMongoParse.java:130)
at com.mudd.heatlab.pawpal.DB.PAWPalDB.getStoredTasks(PAWPalDB.java:106)
at com.mudd.heatlab.pawpal.tasklist.TaskListFragment.onCreate(TaskListFragment.java:66)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1477)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:893)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
at com.mudd.heatlab.pawpal.tasklist.TaskListActivity.displayTaskList(TaskListActivity.java:67)
at com.mudd.heatlab.pawpal.tasklist.TaskListActivity.onCreate(TaskListActivity.java:31)
at android.app.Activity.performCreate(Activity.java:5248)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2173)
非常感谢任何帮助。谢谢!
答案 0 :(得分:0)
public void getStoredTasks(CallbackHandler<ArrayList<PAWTask>> handler) {
GetTasksTask task = new GetTasksTask(mongoDB, handler);
task.doInBackground();
}
替换为
public void getStoredTasks(CallbackHandler<ArrayList<PAWTask>> handler) {
GetTasksTask task = new GetTasksTask(mongoDB, handler);
task.execute();
}
AsyncTask控制着BackThread ..