Java从Thread和Runnable获得结果

时间:2014-10-04 12:45:50

标签: java android android-handler

在下面的代码中,我无法从getValue类中获取Foo的结果,那将返回null,但这必须是返回值。结果是正确的,这个函数无法返回。例如,这是我的班级:

public class JsonService {
    private JSONObject json = new JSONObject();
    public JsonService(final String username, final String password) throws Exception{
        json.put("username", username);
        json.put("password", password);
    }
    public class Foo implements Runnable {
        private String result;

        @Override
        public void run() {
            HttpClient client = new DefaultHttpClient();
            HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
            HttpResponse response;

            try {
                HttpPost post = new HttpPost("http://www.example.com/json_android.php");
                StringEntity se = new StringEntity( json.toString());
                se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                post.setEntity(se);
                response = client.execute(post);
                if(response!=null){
                    InputStream stream = response.getEntity().getContent();
                    result = convertToString(stream);

                    /*
                         I can Log result with below line
                    */
                    Log.e("response is: ", result);

                    /*
                         result is {"username = ":"Hello"}
                    */
                }
            } catch(Exception e) {
                e.printStackTrace();
                Log.e("Error", String.valueOf(e));
            }
        }

        public String getValue() {
            /*
                 return in this fucntion not working
            */
            return result;
        }
    }
    public String request() throws ExecutionException, InterruptedException {
        Foo foo = new Foo();
        new Thread(foo).start();
        return foo.getValue();
    }

如何从Foo正确获取结果并从reauest()返回结果?请帮我。感谢

2 个答案:

答案 0 :(得分:2)

使用FutureTask并实施Callable

public class Foo implements Callable<String> {

    @Override
    public String call() {
        String result = null;
        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
        HttpResponse response;

        try {
            HttpPost post = new HttpPost("http://www.example.com/json_android.php");
            StringEntity se = new StringEntity( json.toString());
            se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
            post.setEntity(se);
            response = client.execute(post);
            if(response!=null){
                InputStream stream = response.getEntity().getContent();
                result = convertToString(stream);

                /*
                     I can Log result with below line
                */
                Log.e("response is: ", result);

                /*
                     result is {"username = ":"Hello"}
                */
            }

        } catch(Exception e) {
            e.printStackTrace();
            Log.e("Error", String.valueOf(e));
        }
        return result;
    }
}

而不是将它与FutureTask一起使用

public String request() throws ExecutionException, InterruptedException {
   Foo foo = new Foo();
   FutureTask<String> fooFuture = new FutureTask<String>(foo);
   new Thread(fooFuture).start();
   return fooFuture.get();
}

答案 1 :(得分:0)

来自类get的{​​{1}}的方法(在上面的答案FutureTask)是一个阻塞函数,这意味着当你从UI线程调用它时它会阻止UI线程,因此导致你的应用程序向您发送return fooFuture.get();错误。我的建议是使用ANR,当计算结束时,它会发送一个本地LocalBroadCastManager,在您的用户界面中,您将从broadcast的{​​{1}}获得结果嵌入意图中。 另一个解决方案是使用onReceive或从UI线程传递处理程序。最后一个是使用Extra小部件方法。