我正在尝试构建一个“随机文章”对象,这意味着来自维基百科的随机解析文章。我需要让本文同步的过程,以便控制正在运行的代码的顺序。
这是我的班级:
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
我试图通过这个答案并在我的代码中实现它。
我想知道如何修复它。谢谢。
答案 0 :(得分:1)
由于get()
阻塞直到有结果,因此考虑您的代码有两种可能性:
JsonObjectRequest
超时或因异常而失败。如果没有看到您的日志输出,则无法确定是否发生了这种情况。此外,您没有记录该失败的原因,因此即使日志包含“失败”行,确切的原因仍然不清楚。null
,但似乎只有在解析过程中发生错误时才会出现这种情况,这会导致ExecutionException
被抛出。改善日志记录是一个好主意,这样您就可以准确了解故障发生的位置和原因。
答案 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;
}
}
}