Java Android right方法:应该在哪里解析JSON响应-在UI线程中,还是在另一个线程中?

Java Android right方法:应该在哪里解析JSON响应-在UI线程中,还是在另一个线程中?,java,android,json,multithreading,Java,Android,Json,Multithreading,我只是想知道-从web服务器接收的JSONObject或JSONArray应该在Android应用程序中解析到哪里-在主UI中,还是应该传递到另一个 例如,我正在使用Volley库: private void fetchResults(){ RequestQueue queue = Volley.newRequestQueue(mContext); String url = AuthenticationRequester.URL_GET_ALL_ORDERS;

我只是想知道-从web服务器接收的
JSONObject
JSONArray
应该在Android应用程序中解析到哪里-在主UI中,还是应该传递到另一个

例如,我正在使用Volley库:

private void fetchResults(){

    RequestQueue queue = Volley.newRequestQueue(mContext);
        String url = AuthenticationRequester.URL_GET_ALL_ORDERS;
        JsonArrayRequest jsonDepartureObj = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray jsonArray) {
                iVolleyCallback.onJSONArraySuccess(jsonArray);
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
                // hide the progress dialog
            }
        });
        queue.add(jsonDepartureObj);
}
private void fetchResults(){
RequestQueue=Volley.newRequestQueue(mContext);
字符串url=AuthenticationRequester.url\u获取\u所有\u订单;
JsonArrayRequest jsonDepartureObj=新的JsonArrayRequest(url,new Response.Listener()){
@凌驾
公共void onResponse(JSONArray JSONArray){
onJSONArraySuccess(jsonArray);
}
},new Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
d(标记“Error:+Error.getMessage());
//隐藏进度对话框
}
});
add(jsonDepartureObj);
}
那么我应该把
iVolleyCallback.onJSONArraySuccess(jsonArray)在另一个线程中执行,或者可以在主UI线程中维护

让我们想象一下,传入的JSON很大,需要一些时间来处理


同样的问题与AsyncTask以及Android中使用web服务的其他可能方式有关

我们建议,每个花费很长时间的任务都应该在另一个线程中处理,以避免重载
主线程

AsyncTasks理想情况下应用于短期操作(最多几秒钟)。如果需要让线程长时间运行,强烈建议您使用java.util.concurrent包提供的各种API,如和


因此,如果您知道您拥有大数据并且需要时间,那么您将使用新线程,但是如果数据小且花费的时间少,为什么要冒险呢?将其移动到新线程

如果,正如您自己所说,JSON数据可能非常庞大,并且可能需要一些时间来处理,我认为您可以(或者应该?)尝试在
异步任务
中处理它。通过这样做,您的UI线程不会在处理过程中冻结。

在大多数GUI设计(不仅仅是Android)中,有几个线程具有不同的角色和职责:

  • “主线程”以“正常”调度优先级运行,基本上除了迅速响应用户界面系统的需求之外别无选择。当“消息”到达以供使用时,该线程立即抢占其他线程,以便可以快速处理消息。像任何优秀的经理一样…;-)。。。他们自己不做这项工作。他们把它传给别人

  • 当涉及异步请求(JSON…等)时,通常会有一个小的线程“池”,负责将这些线程发送到主机,接收响应,进行编码/解码,然后对响应执行操作或传递响应。这些线程几乎所有的时间都在主机上等待。它们的调度优先级稍低

  • 工作线程以更低的优先级运行,执行任何计算耗时的工作。尽可能多地,这些线程不做太多的I/O。它们很快、很容易地将它们的时间片放弃给任何其他线程,但它们通常会在能够获得时间片时消耗掉它们的全部时间片


潜在的长时间运行操作应始终在单独的线程上进行,或者任何可以在单独线程上完成的工作(在合理范围内…)都应在单独的线程上进行

在您的情况下,您使用的是截击,因此很容易覆盖
请求
解析网络响应(网络响应)
;方法,并在传递之前在后台线程上解析响应(因为此方法已在后台线程上运行)。因为这样做是相对无缝的,所以没有理由不在后台线程上解析响应。

试试这个

//使用自定义侦听器排队
RequestManager.queue()
.useBackgroundQueue()
.addRequest(新TestJsonRequest(),mRequestCallback)
.start();
private RequestCallback mrrequestcallback=new RequestCallback(){
@凌驾
公共结果类型doInBackground(JSONObject响应){
//解析并保存响应数据
返回新的ResultType();
}
@凌驾
public void onPostExecute(结果类型结果){
//在此处更新用户界面
Toast.makeText(getApplicationContext(),“来自UI的Toast”,Toast.LENGTH\u SHORT.show();
}
@凌驾
公共无效onError(截击错误){
//在此处处理错误(UI线程)
L.e(error.toString());
}
};

您真的一次需要所有这些数据吗?或者你可以只加载前20条记录来减少大小?然后,如果用户向下滚动或接近查看下一组记录,请加载下一组20。这是最好的解决方案吗?也许凌空截击,使用改进的线程是更好的?我不知道它是否是最好的,但我可以说,
main-thread
中发生的任何事情都会影响它,如果它与任何
UI
无关,它会给你一个延迟(甚至可能是非常小的延迟)。所以我建议您最好在
new-thread
中解析
jsonArray
//Queue using custom listener
RequestManager.queue()
    .useBackgroundQueue()
    .addRequest(new TestJsonRequest(), mRequestCallback)
    .start();

private RequestCallback mRequestCallback = new RequestCallback<JSONObject, ResultType>() {  
@Override
public ResultType doInBackground(JSONObject response) {
    //parse and save response data
    return new ResultType();
}

@Override
public void onPostExecute(ResultType result) {
    //update UI here
    Toast.makeText(getApplicationContext(), "Toast from UI", Toast.LENGTH_SHORT).show();
}

@Override
public void onError(VolleyError error) {
    //handle errors here (UI thread) 
    L.e(error.toString());
}
};