我知道我可能会向后退一步,但还没有找到合适的解决方案,这是我最接近的解决方案。我首先向用户呈现Login视图,并将输入的凭据提交给验证凭据的Web服务,如果登录成功,则返回HTTP 200。成功后,我正在向同一个Web服务发出HTTP JSON请求,以下载JSON对象列表。然后解析这些对象,并将其放入SQLite DB中。大约有100个或更多对象,因此异步任务很吸引人,因此我不会锁定UI。这一点是向用户显示ProgressBar(不确定),说明后台正在进行工作,然后在填充数据库后将它们返回到单独的Intent。以下是代码段:
验证登录并调用登录操作:
switch(statusCode) {
case 200:
PrepareLogin doLogin = new PrepareLogin();
doLogin.execute();
if (doLogin.getStatus().equals(AsyncTask.Status.FINISHED)) {
// Redirect to intent?
}
break;
case 401:
Toast.makeText(Login.this, "Invalid Username/Password", Toast.LENGTH_LONG).show();
}
后台有辅助函数的异步任务:
private class PrepareLogin extends AsyncTask<Void,Void,Void> {
ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(Login.this);
dialog.setTitle(getString(R.string.get_login_dialog_title));
dialog.setMessage(getString(R.string.get_login_dialog_message));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
Looper.myLooper().prepare();
Looper.myLooper().loop();
DBHelper dbHelp = new DBHelper(Login.this);
WSHelper wsHelp = new WSHelper();
long timeNow = System.currentTimeMillis();
dbHelp.resetDB(Login.this); // For dev environment only...remove in prod
dbHelp.create();
dbHelp.createUser(username, password, timeNow, "false");
dbHelp.close();
wsHelp.getEmployees(Login.this, username, password);
Looper.myLooper().quit();
return null;
}
protected void onPostExecute() {
Intent myIntent = new Intent(login.getContext(), Main.class);
startActivityForResult(myIntent, 0);
dialog.dismiss();
}
}
我可以使用Looper.myLooper.prepare()
函数来解决“Handler必须准备一个looper”错误的唯一方法。
我可以在日志中看到建立连接并填充数据库,但对话框继续旋转,它永远不会到达异步任务的onPostExecute()
功能。它会点击Looper.myLooper().quit();
行。
任何建议?
答案 0 :(得分:0)
如果你得到“Handler必须准备一个looper”错误,很可能你是在错误的上下文中调用AsyncTask。我不记得我曾经需要在任何AsyncTask中显式调用Looper.prepare()
函数。一旦你摆脱了looper,它会很好,AsyncTask是Android中最容易使用的类之一。你应该在Login类中发布你的代码(我想它是一个Activity,对吧?)。
我能找到的另一个问题是:
case 200:
PrepareLogin doLogin = new PrepareLogin();
doLogin.execute();
if (doLogin.getStatus().equals(AsyncTask.Status.FINISHED)) {
// Redirect to intent?
}
break;
您的doLogin.execute();
不应该是阻止通话,因此下一个if
保证是错误的,因此重定向永远不会被触发。
答案 1 :(得分:0)
看来我的WSHelper类试图从后台进程对UI进行某种更改。通过从AsyncTask中删除wsHelp初始化并使其成为常量,我能够正常进行。值得注意的是,我将wsHelp.getEmployees()方法的返回值更改为void。