Android UI挂在JDBC连接上-即使连接在另一个线程上



所以,我有一个登录屏幕。按下"登录"Button后,JDBCConnection将检查用户名和密码,如果详细信息正确,则转到下一个Activity。因此,UI将挂起大约5秒钟。我认为这是因为连接是在同一个Thread中创建的,所以我创建了一个新的连接。然后,我创建了一个Handler来与UI交互,具体取决于这个连接发生了什么。

问题是,UI仍然挂起。下面是在活动中声明新Runnable的位置(h是属于该Activity的自定义Handler引用);

logInButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
progress.setVisibility(ProgressBar.VISIBLE);
new LoginProcessor(h).run(); // HERE!
}});            

下面是来自LoginProcessorRunnable的run()方法,其中包括导致挂起的代码。MicroManager类包含简单的JDBC数据库交互,并建立连接(实际上没有什么令人兴奋的,我正在努力使其尽可能短);

public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
try{                   
MicroManager manager = new MicroManager(); // THIS LINE, AND THE LINE BELOW, ARE CAUSING THE HANG!!!!
if(manager.getEmployeeId(h.getLoginName(), h.getPassword())!= 0){
h.sendEmptyMessage(0);
}
}catch(Exception ex){
ex.printStackTrace();
h.sendEmptyMessage(1);
}        
}

在上面的内容中,没有与UI直接交互。信息被简单地发送到Handler,以便它可以在UI线程上执行。最后,这里是我的自定义Handler的方法,称为LogInHandler

@Override
public void handleMessage(Message msg){
if(msg.what == 0){
activity.startActivity(new Intent(activity, AdvisorsPanelActivity.class));
activity.finish();
}else{
AlertDialog alertDialog = new AlertDialog.Builder(activity).create();               
alertDialog.setTitle("Not Working");
alertDialog.show();
activity.setProgressVisible(ProgressBar.GONE);
}
}
public String getLoginName(){
return activity.getLoginName();
}
public String getPassword(){
return activity.getPassword();
}   

很抱歉在你们身上丢了这么多代码,但我认为如果没有以上所有内容,就不可能有一个完整的画面。我已经尽我所能把它修剪掉了。我最近才开始使用线程和安卓系统,所以请对我温和一点。

根据我的经验:对JDBC使用AsyncTask,你就不会再折磨了。

编辑:

这是实现AsyncTask的一个很好的例子:

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
// because we implement OnClickListener we only have to pass "this"
// (much easier)
btn.setOnClickListener(this);
}
public void onClick(View view) {
// detect the view that was "clicked"
switch (view.getId()) {
case R.id.button1:
new LongOperation().execute("");
break;
}
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Executed";
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
}
}

您可能希望在中创建并处理JDBC连接doInBackground(String…params)是代码的一部分。

祝你好运。

最新更新