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

时间:2014-02-19 14:12:40

标签: java android multithreading jdbc android-handler

所以,我有一个登录屏幕。按下“登录”Button后,将生成JDBC Connection以检查用户名和密码,如果详细信息正确,则转到下一个Activity。结果,UI挂起大约5秒钟。我认为这是因为连接是在同一个Thread中创建的,所以我创建了一个新连接。然后,我根据此连接发生的情况创建了Handler以与UI进行交互。

问题是,用户界面仍然悬而未决。下面是在活动中声明新Runnable的位置(h是属于此Handler的自定义Activity引用);

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

以下是LoginProcessor Runnable中的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();
}   

很抱歉把这么多代码转发给你们的人,但是如果没有上述所有内容,我认为没有完整的图片。我尽可能地减少了它。我最近才开始使用线程和Android,所以请温柔地对待我。

1 个答案:

答案 0 :(得分:1)

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

编辑:

This是实现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)代码的一部分。

祝你好运。