rap*_*ock 11 java android network-programming future android-volley
在我的片段中,我正在尝试使用TMDB的开放电影数据库来获取有关"正在播放"电影的详细信息.
如果我使用RequestFuture.get(time,TimeUnit)方法来执行此排球请求,我总是会收到超时错误.如果我在Safari中手动测试相同的Url,我会立即得到结果.
我知道的:
1.)它不是任何JSON解析错误.(程序甚至没有进入解析步骤)
2.)AVD没有互联网问题.(后面解释的原因).
3.)我的凌空单件类或我的请求队列不是问题.(后来解释的原因).
所以我认为我在排球/请求未来的使用方面犯了另一个错误.
片段代码如下:
public class BoxOffice extends android.support.v4.app.Fragment {
private VolleySingleton volleySingleton;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private ArrayList<MyMovie> movieList;
private MyUriBuilder mBuilder;
public BoxOffice() {
// Required empty public constructor
volleySingleton = VolleySingleton.getInstance();
requestQueue = volleySingleton.getRequestQueue();
mBuilder = new MyUriBuilder();
movieList = new ArrayList<>();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
StepA();
}
public void StepA() {
String url = mBuilder.getURL("box");
Log.d("RT", "StepA initiated - "+ url); // Url is perfect - works when copied in Safari.
RequestFuture<JSONObject> futureA = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, (String) null, futureA, futureA);
requestQueue.add(request);
try {
JSONObject response = futureA.get(30, TimeUnit.SECONDS);
Log.d("RT", "StepA - response received"); //Never reaches this step
parseJsonFeed(response);
} catch (InterruptedException e) {
Log.e("RT", "StepA - InterruptedException - " + e);
e.printStackTrace();
} catch (ExecutionException e) {
Log.e("RT", "StepA - ExecutionException - " + e);
e.printStackTrace();
} catch (TimeoutException e) {
Log.e("RT", "StepA - TimeoutException - " + e);
e.printStackTrace();
}
Log.d("RT", "StepA END");
}
public void parseJsonFeed(JSONObject response) {
Log.d("RT", "StepA - parseFeed Begin");
if (response == null || response.length() == 0) {
return;
}
MyMovie currentMovie = null;
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
if (response.has("results")) {
Log.d("RT", "StepA - results");
JSONArray resultList = response.getJSONArray("results");
for (int i = 0; i < 3; i++) {
Log.d("RT", "movie " + i);
JSONObject movieElement = resultList.getJSONObject(i);
if (movieElement.has("id") && movieElement.has("title")) {
currentMovie = new MyMovie();
currentMovie.setTmdb_id(movieElement.getString("id"));
currentMovie.setTitle(movieElement.getString("title"));
if (movieElement.has("release_date")) {
currentMovie.setReleaseDate(dateFormat.parse(movieElement.getString("release_date")));
} else {
currentMovie.setReleaseDate(dateFormat.parse("0000-00-00"));
}
movieList.add(i, currentMovie);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("RT", "StepA - parseFeed END");
}
}
Run Code Online (Sandbox Code Playgroud)
Logcat带有标签"RT"的过滤器:
05-30 15:17:51.710 D/RT? TL - Constructor Called
05-30 15:17:51.800 D/RT? StepA initiated - https://api.themoviedb.org/3/movie/now_playing?api_key=##### (link works fine)
05-30 15:18:21.820 E/RT? StepA - TimeoutException - java.util.concurrent.TimeoutException
05-30 15:18:21.820 D/RT? StepA END
Run Code Online (Sandbox Code Playgroud)
在使用RequestFuture方法之前,我基本上做了同样的事情,在我的片段oncreate中实现我自己的Response.Listener和Response.ErrorListener(而不是StepA();)并且它工作了!
以下是代码片段:
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, mBuilder.getURL("box"), (String) null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
parseJsonFeed(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
});
requestQueue.add(request);
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,当我实现请求未来方法时,为什么它不起作用?
如果你问我为什么要进行同步截击实施; 这是因为在此之后我必须再提出两个完全成功完成的请求.而且我也在学习:)
rap*_*ock 16
很遗憾,没有人可以帮助回答这个问题,但我设法解决了这个问题,如下所示:
如果RequestFuture.get()与UI线程在同一个线程上,则会发生超时.我已经更改了请求的机制,以便请求在单独的Asynch线程(而不是UI线程)上完成,并且响应也在请求的单独线程上接收,如下所示:
private void StepA() {
Log.d("RT", "StepA initiated");
final CountDownLatch latchA = new CountDownLatch(1);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Log.d("RT", "Thread t Begins");
ThreadA threadA = new ThreadA();
try {
JSONObject jsonObject = threadA.execute().get(10, TimeUnit.SECONDS);
parseA(jsonObject);
latchA.countDown();
Log.d("RT", "Thread t Ends");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
});
t.start();
try {
latchA.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("RT", "StepA END");
}
Run Code Online (Sandbox Code Playgroud)
以下是请求的Asynch任务代码:
protected class ThreadA extends AsyncTask<Void, Void, JSONObject> {
final String url = mBuilder.getURL("box");
public ThreadA() {
}
@Override
protected JSONObject doInBackground(Void... params) {
final RequestFuture<JSONObject> future = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, (String) null, future, future);
requestQueue.add(request);
try {
return future.get(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了倒计时锁存器,因为它们很棒,也导致我在我的程序中有更多这样的请求依赖于这个片段的响应.因此,它们可以帮助更加同步地运行程序.
| 归档时间: |
|
| 查看次数: |
7634 次 |
| 最近记录: |