简体   繁体   English

如何从java中的线程返回一个值?

[英]How to return a value from thread in java?

In android i am creating thread for url connection.Inside the thread i store the response message in a string which is globally declared.When I access the method method it returns null. 在android我正在为url连接创建线程。在线程中我将响应消息存储在全局声明的字符串中。当我访问方法方法时,它返回null。

    public class Rate_fetch {
       String total="";
          public String  rate(String dt)
       {
    new Thread(new Runnable(){ 

         public void run(){


            try  {

             URL url = new URL(tally_ipaddr+"/prorate.jsp?plist="+sss.toString().trim());

             HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
             InputStream in = new BufferedInputStream(urlConnection.getInputStream());
             BufferedReader r = new BufferedReader(new InputStreamReader(in));
             String x = "";
             String total = "";
             x = r.readLine();
             int i=0;

             while(x.length()>1)
             {
                 total=total+x.toString().trim();
                 i++;
                 x = r.readLine();
             }
             }
            catch(Exception e){
             return e.toString();
            }   
        }    

    }).start();

    return total;



}

When i call the method it returns null. 当我调用该方法时,它返回null。

 Rate_fetch rf=new Rate_fetch();
      String amt= rf.rate(prodList);

It you really want to use Thread only, try this 你真的想只使用Thread ,试试吧

    public class Rate_fetch {
    String total = "";
    boolean b = true;

    public String rate(String dt) {
        StringBuilder sb = new StringBuilder();
        new Thread(new Runnable() {

            public void run() {

                try {

                    URL url = new URL(tally_ipaddr + "/prorate.jsp?plist="
                            + sss.toString().trim());

                    HttpURLConnection urlConnection = (HttpURLConnection) url
                            .openConnection();
                    InputStream in = new BufferedInputStream(urlConnection
                            .getInputStream());
                    BufferedReader r = new BufferedReader(
                            new InputStreamReader(in));
                    StringBuilder sb = new StringBuilder();
                    String s;
                    while (true) {
                        s = r.readLine();
                        if (s == null || s.length() == 0)
                            break;
                        sb.append(s);
                    }
                    b = true;
                } catch (Exception e) {
                    b = true;
                }
            }

        }).start();
        while (b) {

        }
        total = sb.toString();
        return sb.toString();

    }
}

You are getting the value of result as null because the method rate is running a thread so the return is not waiting to finish the thread. 您将result的值设置为null,因为方法rate正在运行一个线程,因此return不等待完成线程。

You can use one of the following technique to resolve the issue 您可以使用以下技术之一来解决此问题

  • Handlers 处理程序
  • Async. 异步。 Task 任务

Also you can look at the link for the reference. 您也可以查看参考链接。

http://mobileorchard.com/android-app-developmentthreading-part-1-handlers/ http://mobileorchard.com/android-app-developmentthreading-part-1-handlers/

You are missing the whole point of using a thread, because we use them to do expensive or potentially long operation in a separate thread in order to not block the UI thread. 您错过了使用线程的全部要点,因为我们使用它们在单独的线程中执行昂贵或可能很长的操作,以便不阻止UI线程。 Therefore, you can not start a thread and expect to get the result instantly, as Premsuraj, it returns before the thread has finished. 因此,您无法启动线程并期望立即获得结果,如Premsuraj,它在线程完成之前返回。

As others suggested, a cleaner way to do this would be to use an AsyncTask, it encapsulates the process in three main stages: OnPreExecute, doInBackground and onPostExecute, they names are self-explanatory, the first do any initialization you might need, the second actually do the async work and the third is used to deal with the result of the entire operation. 正如其他人所说,更简洁的方法是使用AsyncTask,它将进程封装在三个主要阶段:OnPreExecute,doInBackground和onPostExecute,它们的名称是不言自明的,第一个是你可能需要的初始化,第二个实际上做异步工作,第三个用于处理整个操作的结果。

Here's one quick example, of course it can be improved but should help you to understand it: 这是一个简单的例子,当然它可以改进,但应该帮助你理解它:

Rate_fetch Rate_fetch

Your same class but without threading: 同一个班级但没有线程:

public class Rate_fetch {

       public String rate(String dt)
       {
            String total="";
            try  {

                URL url = new URL(tally_ipaddr+"/prorate.jsp?plist="+sss.toString().trim());

                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                BufferedReader r = new BufferedReader(new InputStreamReader(in));
                String x = "";
                String total = "";
                x = r.readLine();
                int i=0;

                while(x.length()>1)
                {
                    total=total+x.toString().trim();
                    i++;
                    x = r.readLine();
                }
            }
            catch(Exception e){
                return e.toString();
            };

            return total;
        }

    }

An example activity: 一个示例活动:

public class YourActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.layout);

        GetRate asyncRate = new GetRate();
        asyncRate.execute(); // starting the task, can be done wherever you need, for example a Button click event
    }

    private class GetRate extends AsyncTask<Void, Integer, String> {

        @Override
        protected String doInBackground(Void... params) {

            Rate_fetch fetch = new Rate_fetch();
            string rate = fetch.rate();

            return rate;
        }

        @Override
        protected void onPostExecute(String rate) {                     
            // Do whatever you need with the string, you can update your UI from here
        }
    }

}

Hope it helps. 希望能帮助到你。

possibly you can pass reference of main/current thread/class to the thread. 可能你可以将主/当前线程/类的引用传递给线程。 and thread will store its result in that referenced object. 和线程将其结果存储在该引用的对象中。

Below is a simple example. 下面是一个简单的例子。

class CallerTest{
 private ResultData result; // any data that you want from thread

 public void caller() throws Exception{
   ThreadClass thread = new ThreadClass(this);
   thread.start();

   //wait for thread to finish
   thread.join();

   //now you have data in >> this.result
 }

 public void setResult(ResultData rd){
   this.result = rd; 
 }
}

class ThreadClass extends Thread{
    CallerTest cl;
    public ThreadClass(CallerTest cl){
       this.cl = cl;
    }
    public void run() {
     ResultData rd;
     rd = //do code to retrive result
     cl.setResult(rd);
    }

}

只需声明一个类变量并将该对象传递给您的线程

You can't return a value from a thread. 您无法从线程返回值。 Your function Rate_fetch would return before the thread has even started executing. 你的函数Rate_fetch会在线程开始执行之前返回。 A solution is to use AsyncTask and use the value in its onPostExecute. 解决方案是使用AsyncTask并使用其onPostExecute中的值。

If you choose to use a separate thread to execute your logic is implicit that the execution of the code inside of your thread will be asynchronous, so you cannot access the result immediatly ignoring the asynchronous thread execution. 如果您选择使用单独的线程来执行您的逻辑,那么隐含的是线程内部代码的执行将是异步的,因此您无法立即访问结果而忽略异步线程执行。 You should consider to use something like http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html 您应该考虑使用类似http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html的内容

看一下Thread Local ,它会让你携带一个参数,其中thread是它自己的局部变量。

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

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