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

时间:2013-03-13 07:39:41

标签: java android multithreading

在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;



}

当我调用该方法时,它返回null。

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

8 个答案:

答案 0 :(得分:4)

你真的只想使用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();

    }
}

答案 1 :(得分:2)

您将result的值设置为null,因为方法rate正在运行一个线程,因此return不等待完成该线程。

您可以使用以下技术之一来解决问题

  • 处理程序
  • 异步。任务

您也可以查看参考链接。

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

答案 2 :(得分:1)

您缺少使用线程的全部意义,因为我们使用它们在单独的线程中执行昂贵或可能很长的操作,以便不阻止UI线程。因此,你无法启动一个线程并期望立即获得结果,就像Premsuraj一样,它会在线程完成之前返回。

正如其他人所说,更简洁的方法是使用AsyncTask,它将进程封装在三个主要阶段:OnPreExecute,doInBackground和onPostExecute,它们的名称是不言自明的,第一个进行任何初始化,你可能需要,第二个实际上是异步工作,第三个是用来处理整个操作的结果。

这是一个简单的例子,当然它可以改进,但应该帮助你理解它:

Rate_fetch

同一个班级,但没有线程:

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

    }

示例活动:

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
        }
    }

}

希望它有所帮助。

答案 3 :(得分:1)

可能你可以将主/当前线程/类的引用传递给线程。和线程将其结果存储在该引用的对象中。

下面是一个简单的例子。

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

}

答案 4 :(得分:0)

只需声明一个类变量并在线程中传递对象

答案 5 :(得分:0)

您无法从线程返回值。你的函数Rate_fetch会在线程开始执行之前返回。 解决方案是使用AsyncTask并使用其onPostExecute中的值。

答案 6 :(得分:0)

如果您选择使用单独的线程来执行您的逻辑,则隐含在您的线程内部执行代码将是异步的,因此您无法立即访问结果而忽略异步线程执行。 您应该考虑使用类似http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html

的内容

答案 7 :(得分:0)

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