I'm trying to build a "Random Article" Object, which means a random parsed article from Wikipedia. I need the process of getting this article to be synchronous, in order to control the order of the running code.
This is my class:
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;
}
}
}
This is the problematic line:
return future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);
It's just timing out, and then the result becomes null.
This is the error I get:
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)
I have searched online a lot in order to find something that is similar to what I need. This answer was the best match: https://stackoverflow.com/a/30569997/7483311
I have tried to go through this answer and implement it in my code.
I would like to know how to fix it. Thanks.