[英]Android - Return boolean value from within a Thread
我試圖從Thread
的runnable
方法返回boolean
值。 我需要知道HTTPRequest
方法是否成功。 問題是我知道請求成功,但是響應總是false
。
public boolean SmsDelivery;
SmsDelivery=sendSMS(prefix, number);
if(SmsDelivery){
//Do stuff
}
//The method itself
private boolean sendSMSinThread(final String str){
final AtomicBoolean b = new AtomicBoolean(false);
Thread thread = new Thread(new Runnable(){
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(str);
@Override
public void run() {
try {
// Execute HTTP Post Request
//HttpResponse response = httpclient.execute(httppost);
httpclient.execute(httppost);
b.set(true);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
Log.e("Thread:","Unable to generate call"+e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Thread:","Unable to generate call"+e);
}
}
});
thread.start();
return b.get();
}
更新
根據這里的建議,我設法獲得了預期的結果,但是,我不知道哪種方法更適合我的需求。 有人可以推薦最適合我的情況嗎? 使用AsyncTask
或Thread + join
方法。
第一種方法是通過以下方式使用AsyncTask:
SmsTask smsTask = new SmsTask();
try{
smsResult = smsTask.execute(urlString).get();
}catch (InterruptedException e){
e.printStackTrace();
}catch (ExecutionException e){
e.printStackTrace();
}
//the class itself
class SmsTask extends AsyncTask<String,Void, Boolean> {
final AtomicBoolean b = new AtomicBoolean(false);
@Override
protected Boolean doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
httpclient.execute(httppost);
b.set(true);
} catch (IOException e) {
e.printStackTrace();
}
return b.get();
}
@Override
protected void onPostExecute(Boolean result) {
// result holds what you return from doInBackground
Log.i("result from async: ",""+result);
super.onPostExecute(result);
}
}
第二種方法,幾乎和我最初發布的一樣,但是使用了“ thread.join()”方法:
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return b.get();
您應該等待直到任務執行完畢。 在這種情況下,您應該在單線程中運行此代碼(新線程無效)或使用onPostExecute
Android的AsyncTask
類,並在onPostExecute
方法中處理結果。
您可以使用一些觀察者模式或其他方式。
像這樣:
//具有自定義的Runnable
public class HTTPRequestRunnable implements Runnable {
HttpClient httpclient;
HttpPost httppost;
private HTTPRequestListner listner;
public HTTPRequestRunnable(String str, HTTPRequestListner listner) {
httpclient = new DefaultHttpClient();
httppost = new HttpPost(str);
this.listner = listner;
}
@Override
public void run() {
try {
// Execute HTTP Post Request
//HttpResponse response = httpclient.execute(httppost);
httpclient.execute(httppost);
if (listner != null)
listner.onSuccess();
} catch (ClientProtocolException e) {
if (listner != null)
listner.onFail();
Log.e("Thread:", "Unable to generate call" + e);
} catch (IOException e) {
if (listner != null)
listner.onFail();
e.printStackTrace();
Log.e("Thread:", "Unable to generate call" + e);
}
}
public void setListner(HTTPRequestListner listner) {
this.listner = listner;
}
/**
* here is your observer class
*/
public interface HTTPRequestListner {
void onSuccess();
void onFail();
}
}
然后在您的方法中像這樣使用它:
public void sendSMSinThread(final String str){
HTTPRequestRunnable httpRequestRunnable = new HTTPRequestRunnable(str,new HTTPRequestListner() {
@Override
public void onSuccess() {
//DO your logic here on success
}
@Override
public void onFail() {
//DO your logic here on fail
}
});
Thread thread = new Thread(httpRequestRunnable);
thread.start();
}
您來了,我希望它將對您有幫助
有多種方法可以實現此目的。
堅持您的方法,但是在返回結果之前,請調用thread.join()
thread.start(); thread.join(); return b.get();
缺點
如果要發送數千條SMS,它將創建那么多線程。 這里沒有使用線程創建功能,因為您可以使用傳入線程本身來發送SMS。
使用可運行和未來。
一種。 為每個SMS創建一個SendSms對象,
b。 最多將創建10個線程。
C。 發送SMS和getSMSdelivery將是同步事件。 因此,對於每個發送的SMS,如果您需要的話,您都可以獲取傳遞狀態。
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class SendSms { private static ExecutorService pool = Executors.newFixedThreadPool(10); public boolean submitSms(String message,String phNo) { Runnable run = new SendSMSThread(message,phNo); Future future = pool.submit(run); try { if(null ==future.get()) { return true; } } catch (InterruptedException | ExecutionException e) { // SMS Sending failed. e.printStackTrace(); return false; } return false; } private class SendSMSThread implements Runnable { String message; String phNo; public SendSMSThread(String message,String phNo) { this.message = message; this.phNo = phNo; } public void run() { //Send SMS } } }
以上三種解決方案均受阻。 因此,它將線程保持在阻塞狀態,從而對系統的可伸縮性構成重大威脅。
一種。 使用BlockingQueue。
b。 對於每個SMS請求,將一個SMSObject添加到BlockingQueue。
C。 使用線程池並處理Queue中的對象。
d。 SMS成功發送后,將結果保存到另一個數據結構中。
e。 使用線程池,從上述數據結構中讀取數據,並通知SMS傳遞成功。
嘗試這個
thread.start();
thread.join();
return b.get();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.