Android凌空未来请求正在超时

时间:2017-05-03 18:55:07

标签: java android json multithreading android-volley

我正在尝试构建一个“随机文章”对象,这意味着来自维基百科的随机解析文章。我需要让本文同步的过程,以便控制正在运行的代码的顺序。

这是我的班级:

import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.RequestFuture;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.json.JSONObject;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static android.content.ContentValues.TAG;

public class RandomArticle {

    private RequestQueue requestQueue;
    private Gson gson;
    private String linkForRandomArticle="https://he.wikipedia.org/w/api.php?%20format=json&action=query&prop=extracts&exsentences=2&exintro=&explaintext=&generator=random&grnnamespace=0";
    private String title, firstParagraph, id, link;
    private JSONObject result;
    static Context context;

    public RandomArticle(final Context context){
        requestQueue = Volley.newRequestQueue(context);
        GsonBuilder gsonBuilder = new GsonBuilder();
        gson = gsonBuilder.create();

         new Handler().post(new Runnable() {
    public void run() {
        ThreadA threadA = new ThreadA();
        try{
            try {

                try{
                    result=threadA.execute().get(10, TimeUnit.SECONDS);
                }
                catch (TimeoutException e){
                    Log.e(TAG,Log.getStackTraceString(e));
                }
            }
            catch (InterruptedException e){
                Log.e(TAG,Log.getStackTraceString(e));
            }
        }
        catch (ExecutionException e) {
            Log.e(TAG,Log.getStackTraceString(e));
        }

    }
});


    protected class ThreadA extends AsyncTask<Void, Void, JSONObject> {

        public ThreadA() {
        }

        @Override
        protected JSONObject doInBackground(Void... params) {
            RequestFuture<JSONObject> future = RequestFuture.newFuture();
            final JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST,
                    linkForRandomArticle,
                    new JSONObject(),
                    future, future);

            requestQueue.add(request);

            try {
                try {
                    int REQUEST_TIMEOUT = 10;
                    try{
                        return future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);
                    }
                    catch (TimeoutException e){
                        Log.e(TAG,Log.getStackTraceString(e));

                    }

                } catch (ExecutionException e) {
                    Log.e(TAG,Log.getStackTraceString(e));
                }
            }
            catch (InterruptedException e){
                Log.e(TAG,Log.getStackTraceString(e));
            }

            return null;
        }
    }

}

这是有问题的一行:

 return future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);

它只是超时,然后结果变为空。

这是我得到的错误:

05-05 15:55:39.912 25444-25519/com.example.barda.wikirace E/ContentValues:
java.util.concurrent.TimeoutException
at com.android.volley.toolbox.RequestFuture.doGet(RequestFuture.java:121)
at com.android.volley.toolbox.RequestFuture.get(RequestFuture.java:97)
at com.example.barda.wikirace.RandomArticle$Thread.doInBackground(RandomArticle.java:73)
at com.example.barda.wikirace.RandomArticle$Thread.doInBackground(RandomArticle.java:58)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

我在网上搜索了很多东西,以找到与我需要的东西相似的东西。这个答案是最佳匹配:https://stackoverflow.com/a/30569997/7483311

我试图通过这个答案并在我的代码中实现它。

我想知道如何修复它。谢谢。

3 个答案:

答案 0 :(得分:1)

由于get()阻塞直到有结果,因此考虑您的代码有两种可能性:

  1. JsonObjectRequest超时或因异常而失败。如果没有看到您的日志输出,则无法确定是否发生了这种情况。此外,您没有记录该失败的原因,因此即使日志包含“失败”行,确切的原因仍然不清楚。
  2. 结果是null,但似乎只有在解析过程中发生错误时才会出现这种情况,这会导致ExecutionException被抛出。
  3. 改善日志记录是一个好主意,这样您就可以准确了解故障发生的位置和原因。

答案 1 :(得分:0)

问题在于:

  new Handler().post(new Runnable() {
        public void run() {
            ThreadA threadA = new ThreadA();
            try{
                try {

                    try{
                        result=threadA.execute().get(10, TimeUnit.SECONDS);
                    }
                    catch (TimeoutException e){
                        Log.e(TAG,Log.getStackTraceString(e));
                    }
                }
                catch (InterruptedException e){
                    Log.e(TAG,Log.getStackTraceString(e));
                }
            }
            catch (ExecutionException e) {
                Log.e(TAG,Log.getStackTraceString(e));
            }

        }
    });

而不是:

 Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("RT", "Thread t Begins");
                ThreadA threadA = new ThreadA();
                try{
                    try {

                        try{
                            result=threadA.execute().get(10, TimeUnit.SECONDS);
                        }
                        catch (TimeoutException e){
                            Log.e(TAG,Log.getStackTraceString(e));
                        }
                    }
                    catch (InterruptedException e){
                        Log.e(TAG,Log.getStackTraceString(e));
                    }
                }
                catch (ExecutionException e) {
                    Log.e(TAG,Log.getStackTraceString(e));
                }

            }
        });
        t.start();

它可能必须是新线程。

答案 2 :(得分:0)

使用下面的代码片段稍微更改一下并获得响应

公共类RandomArticle {

private RequestQueue requestQueue;
private Gson gson;
private String linkForRandomArticle = "https://he.wikipedia.org/w/api.php?%20format=json&action=query&prop=extracts&exsentences=2&exintro=&explaintext=&generator=random&grnnamespace=0";
private String title, firstParagraph, id, link;
private JSONObject result;
static Context context;

public RandomArticle(final Context context) {
   this.context = context;
}

 public JSONObject getRamdomArticle(){
     requestQueue = Volley.newRequestQueue(context);
     GsonBuilder gsonBuilder = new GsonBuilder();
     gson = gsonBuilder.create();
     ThreadA threadA = new ThreadA();
     try {
         try {

             try {
                 result = threadA.execute().get(100, TimeUnit.SECONDS);
                 assert result != null;
             } catch (TimeoutException e) {
                 Log.e(TAG, Log.getStackTraceString(e));
             }
         } catch (InterruptedException e) {
             Log.e(TAG, Log.getStackTraceString(e));
         }
     } catch (ExecutionException e) {
         Log.e(TAG, Log.getStackTraceString(e));
     }
     return result;
 }



class ThreadA extends AsyncTask<Void, Void, JSONObject> {

    public ThreadA() {
    }

    @Override
    protected JSONObject doInBackground(Void... params) {
        RequestFuture<JSONObject> future = RequestFuture.newFuture();
        final JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST,
                linkForRandomArticle,
                new JSONObject(),
                future, future);

        requestQueue.add(request);

        try {
            try {
                int REQUEST_TIMEOUT = 100;
                try {
                    return future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);
                } catch (TimeoutException e) {
                    Log.e(TAG, Log.getStackTraceString(e));

                }

            } catch (ExecutionException e) {
                Log.e(TAG, Log.getStackTraceString(e));
            }
        } catch (InterruptedException e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }

        return null;
    }
}

}