Android - 从线程内返回布尔值

时间:2015-03-26 09:02:02

标签: java android multithreading atomicboolean

我尝试在boolean内的runnable方法中返回Thread值。我需要知道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();
    }


更新

根据这里的建议,我设法得到了理想的结果,但是,我不知道哪种方法更适合我的需要。有人可以推荐我的最佳用法吗?使用AsyncTaskThread + 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);
        }
    }


第二种方法,几乎​​就像我最初发布的那样,但是使用了&#39; thread.join()&#39;方法:

thread.start();
try {
    thread.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}
return b.get();

4 个答案:

答案 0 :(得分:2)

您应该等到执行任务。在这种情况下,您应该在单个线程中运行此代码(新线程无用)或使用Android AsyncTask - 类似于onPostExecute方法中的类和处理结果。

答案 1 :(得分:1)

你可以使用一些观察者模式或其他东西。

这样的事情:

//有自定义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();
    }

在这里,我希望它会帮助你

答案 2 :(得分:1)

有多种方法可以实现这一目标。

  1. 使用可调用而不是runnable,因为可调用的调用方法可以返回结果
  2. 坚持你的方法,但在返回结果之前,请调用thread.join()

    thread.start();
    thread.join();
    return b.get();
    

    <强>缺点

    如果要发送数千条短信,它将创建那么多线程。 这里没有使用线程创建,因为传入的线程本身可以发送SMS。

  3. 使用Runnable和Future。

    一个。为每个SMS创建一个SendSms对象,

    湾它将创建最多10个线程。

    ℃。发送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
           }
        }
    }
    
  4. 以上三种解决方案都是封锁的。因此它会使线程保持在BLOCKING状态,从而对系统的可扩展性构成重大威胁。

    一个。使用BlockingQueue。

    湾对于每个SMS请求,将一个SMSObject添加到BlockingQueue。

    ℃。使用线程池并处理队列中的对象。

    d。成功发送SMS后,将结果保存到另一个数据结构。

    即使用线程池,从上面的数据结构中读取数据并通知成功的SMS传递。

答案 3 :(得分:0)

试试这个

thread.start();
thread.join();
return b.get();