我编写了一些代码,在单独的线程中建立连接并检索一些数据。这一切都很好。
当我尝试通过Handler将此信息传回主线程时,我的问题就出现了。
因为离开主线程的线程的代码没有嵌套在主类中,所以传递给处理程序的引用似乎不成立。关于如何修改代码以允许将处理程序数据传递回主线程的建议。
主线程的代码(仅剥离重要位):
public class MyActivity extends Activity {
Handler mHandler = new Handler(){
public void handleMessage(Message msg){
Bundle b;
if(msg.what==1){
b = msg.getData();
weCanMove = b.getBoolean("key");
Log.d("what did we get", String.valueOf(b.getBoolean("key")));
}
super.handleMessage(msg);
}
};
public void start(View view) throws InterruptedException {
Context context;
Boolean weHaveFile = checkFile();
System.out.println(userinfo[0] + "\n" + userinfo[1]);
if (weHaveFile) {
Intent intent = new Intent(MyActivity.this, OtherActivity.class);
startActivity(intent);
} else {
//DatabaseMiddleMan login = new DatabaseMiddleMan();
/*login.run();
login.login(userinfo[0],userinfo[1]);*/
ArrayList <String> uinfo = new ArrayList<String>();
uinfo.add(0,userinfo[0]);
uinfo.add(1,userinfo[1]);
DatabaseMiddleMan login = new DatabaseMiddleMan(0,uinfo,this.mHandler);
Thread thread = new Thread(login);
thread.start();
Thread.sleep();
if(weCanMove) {
Intent intent = new Intent(MyActivity.this, OtherActivity.class);
startActivity(intent);
}else{
context = this.getApplicationContext();
new AlertDialog.Builder(MyActivity.this)
.setTitle("Errore")
.setMessage("Credenziali errate!")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
}
}
在单独的线程中运行的对象的代码:
public class DatabaseMiddleMan implements Runnable{
public String serverAddress;
public boolean loginsucess = false;
private ArrayList<String> params;
private int whichMethodToExecute;
private Handler hd;
public DatabaseMiddleMan(int selection, ArrayList<String> params, Handler msg){
this.params = params;
this.whichMethodToExecute = selection;
hd = msg;
}
public void run(){
if(this.whichMethodToExecute == 0){
this.login();
}
}
public void login(){
String username = params.get(0);
String password = params.get(1);
String link = "xxxxxxxxxxxxxx";
String query = "xxxxxxxxxxxxxxx";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(link);
BasicNameValuePair queryPair = new BasicNameValuePair("query", query);
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
nameValuePairList.add(queryPair);
Bundle b = new Bundle(1);
try {
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairList);
httpPost.setEntity(urlEncodedFormEntity);
try {
HttpResponse httpResponse = httpClient.execute(httpPost);
InputStream inputStream = httpResponse.getEntity().getContent();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String bufferedStrChunk = null;
StringBuilder stringBuilder = new StringBuilder();
while ((bufferedStrChunk = bufferedReader.readLine()) != null) {
stringBuilder.append(bufferedStrChunk);
}
String queryResult = stringBuilder.toString();
Log.d("SQL PASS",queryResult);
if (queryResult.equals(password)){
loginsucess = true;
b.putBoolean("key",true);
Log.d("SQL PASS","test passed");
} else {
b.putBoolean("key",false);
}
} catch (ClientProtocolException cpe) {
System.out.println("First Exception caz of HttpResponese :" + cpe);
cpe.printStackTrace();
} catch (IOException ioe) {
System.out.println("Second Exception caz of HttpResponse :" + ioe);
ioe.printStackTrace();
}
} catch (UnsupportedEncodingException uee) {
System.out.println("An Exception given because of UrlEncodedFormEntity argument :" + uee);
uee.printStackTrace();
}
Message msgs = hd.obtainMessage();
msgs.setData(b);
hd.sendMessage(msgs);
}
答案 0 :(得分:0)
消息循环器是什么?它是一个接收消息队列的对象,并在同一个线程中依次运行消息处理程序。接下来将在上一次完成后运行。
所以,想象一下,有一些启动事件被放入队列中。 looper启动一个处理程序,它将运行级联方法,最后启动 start(View view)。 Looper将暂停,直到所有方法都完成并且处理程序完成。因此,队列中的下一条消息(将运行您的处理程序的 handleMessage )只能在 start 返回后执行。
从不在主线程中使用 Thread.sleep()。最好使用
thread.join();
等待asyn线程完成。
如果你想在线程完成后在线程之间传递一个单个对象,你可以使用这种方法:
在Runnable中分配一些易变量:
public class DatabaseMiddleMan implements Runnable{
public volatile Bundle mResult;
...
在线程完成后,您可以访问此变量:
DatabaseMiddleMan login = new DatabaseMiddleMan(0,uinfo,this.mHandler);
Thread thread = new Thread(login);
thread.start();
...
// blah blah blah, here doing some actions in parallel, while thread doing it's work
...
thread.join();
Bundle b = login.mResult;
weCanMove = b.getBoolean("key");
请注意,您可以在此处传递一个布尔值,而不是 Bundle 。此外,如果需要,您可以创建多个结果变量。