简体   繁体   English

Android-从线程内返回布尔值

[英]Android - Return boolean value from within a Thread

Im trying to return a boolean value from a runnable method within a Thread . 我试图从Threadrunnable方法返回boolean值。 I need to know whether a HTTPRequest method succeeded or not. 我需要知道HTTPRequest方法是否成功。 The problem is I know the request is successful but I always get false as the response. 问题是我知道请求成功,但是响应总是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();
    }


UPDATE 更新

Based on the advices here i managed to get the desired result, however, I dont know which method is more suitable for my needs. 根据这里的建议,我设法获得了预期的结果,但是,我不知道哪种方法更适合我的需求。 Can someone recommend whats the best usage in my case? 有人可以推荐最适合我的情况吗? Using AsyncTask or a Thread + join method. 使用AsyncTaskThread + join方法。
First method is using AsyncTask in the following manner: 第一种方法是通过以下方式使用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);
        }
    }


Second method, almost as I initially posted but with the 'thread.join()' method: 第二种方法,几乎​​和我最初发布的一样,但是使用了“ thread.join()”方法:

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

You should wait until task will be performed. 您应该等待直到任务执行完毕。 In this case you should run this code in single thread (new Thread is useless) or use Android's AsyncTask -like class and process result in onPostExecute method. 在这种情况下,您应该在单线程中运行此代码(新线程无效)或使用onPostExecute Android的AsyncTask类,并在onPostExecute方法中处理结果。

You could use some Observer pattern or something. 您可以使用一些观察者模式或其他方式。

Something like this: 像这样:

// have a custom Runnable //具有自定义的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();
    }
}

Then use it like this in your method: 然后在您的方法中像这样使用它:

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();
    }

Here you go and i hope it will help you 您来了,我希望它将对您有帮助

There are multiple ways to achieve this. 有多种方法可以实现此目的。

  1. Use a callable, instead of runnable, as callable's call method can return result 使用Callable而不是Runnable,因为Callable的call方法可以返回结果
  2. Stick to your approach, but before returning the result, call thread.join() 坚持您的方法,但是在返回结果之前,请调用thread.join()

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

    Drawbacks 缺点

    If there are thousands of SMS to be sent, it will create those many threads. 如果要发送数千条SMS,它将创建那么多线程。 There is no use of thread creation here as you can the incoming thread itself to send SMS. 这里没有使用线程创建功能,因为您可以使用传入线程本身来发送SMS。

  3. Use Runnable and Future. 使用可运行和未来。

    a. 一种。 For each SMS create a SendSms object, 为每个SMS创建一个SendSms对象,

    b. b。 It will create a maximum of 10 threads. 最多将创建10个线程。

    c. C。 The send SMS and getSMSdelivery will be synchronous events. 发送SMS和getSMSdelivery将是同步事件。 So for each SMS sent, you can get the delivery status if that's your requirement. 因此,对于每个发送的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. All the above three solution are blocking. 以上三种解决方案均受阻。 So it will keep the threads in BLOCKING state, thereby posing significant threat to scalability of system. 因此,它将线程保持在阻塞状态,从而对系统的可伸缩性构成重大威胁。

    a. 一种。 Use a BlockingQueue. 使用BlockingQueue。

    b. b。 For each SMS request, add a SMSObject to BlockingQueue. 对于每个SMS请求,将一个SMSObject添加到BlockingQueue。

    c. C。 Use a threadpool and process the objects in Queue. 使用线程池并处理Queue中的对象。

    d. d。 Once the SMS is sent successfully, save the result to another data-structure. SMS成功发送后,将结果保存到另一个数据结构中。

    e. e。 Use a threadpool, read the data from above data-structure and notify about successful SMS delivery. 使用线程池,从上述数据结构中读取数据,并通知SMS传递成功。

Try this 尝试这个

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM