Java 在android中管理多个异步任务
大家好,我刚刚开始在线培训应用程序的第二部分,并尝试调整我的异步任务以从电影数据库获取电影评论。有一个完全不同的异步任务似乎应该有一个更好的方法。下面是当前仅获取电影数据的异步任务实现 问题是我如何添加另一个异步任务,以便从这个url/movie/{id}/videos检索电影评论Java 在android中管理多个异步任务,java,android,asynchronous,Java,Android,Asynchronous,大家好,我刚刚开始在线培训应用程序的第二部分,并尝试调整我的异步任务以从电影数据库获取电影评论。有一个完全不同的异步任务似乎应该有一个更好的方法。下面是当前仅获取电影数据的异步任务实现 问题是我如何添加另一个异步任务,以便从这个url/movie/{id}/videos检索电影评论 public FetchMovieData(Context context, GridView grid, boolean sortType, ITaskCompleteListener listener) {
public FetchMovieData(Context context, GridView grid, boolean sortType, ITaskCompleteListener listener) {
mContext = context;
this.mMoviesGrid = grid;
this.mSortByMostPopular = sortType;
this.mTaskCompleteListener = listener;
}
@Override
protected Void doInBackground(String... params) {
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
URL url;
if(mSortByMostPopular)
url = new URL(mContext.getString(R.string.picasso_url_popular_movies));
else
url = new URL(mContext.getString(R.string.picasso_url_highest_rated));
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
mMovieJsonStr = null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
mMovieJsonStr = null;
}
mMovieJsonStr = buffer.toString();
} catch (IOException e) {
Log.e("PlaceholderFragment", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attempting
// to parse it.
mMovieJsonStr = null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieJsonStr != null)
Constants.mMovies = MovieDataParser.getMovieData(mMovieJsonStr);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
因此,有人建议使用改造,而不是有多个异步任务。这似乎是个好主意,但我很难理解它应该如何工作。目前,我有一个WebService类和一个接口,我正试图用它来检索这两部电影,并将添加评论,然后是预告片。问题是,如果我在logcat中将基本url设置为“I get url必须以“/”开头”
当前代码:
public class WebService {
public List<Movie> getMovies() {
RestAdapter retrofit = new RestAdapter.Builder()
.setEndpoint("http://api.themoviedb.org")
.build();
MovieDBService service = retrofit.create(MovieDBService.class);
return service.listMovies("movies");
}
}
public interface MovieDBService {
@GET("/3/discover/{switchterm}sort_by=popularity.desc&api_key=d273a1a1fb9390dab9 7ac0032b12366a")
List listMovies(@Path("switchterm") String switchterm);
}
//In code getting movies
WebService service = new WebService();
List movies = service.getMovies();
公共类Web服务{
公共列表getMovies(){
RestAdapter翻新=新建RestAdapter.Builder()
.setEndpoint(“http://api.themoviedb.org")
.build();
MovieDBService=reformation.create(MovieDBService.class);
返回服务。列表电影(“电影”);
}
}
公共界面电影服务{
@GET(“/3/discover/{switchterm}sort_by=popularity.desc&api_key=d273a1fb9390dab9 7ac0032b12366a”)
列出listMovies(@Path(“switchterm”)字符串switchterm);
}
//在代码获取电影中
WebService=newwebservice();
List movies=service.getMovies();
我认为您有很多这样做的可能性。您可以遵循以下方法:在第一个任务完成后,向另一个AsyncTask添加第二个调用,并向其传递带有视频ID的字符串列表:
public class FetchMovieData extends AsyncTask<Void, Void, Void> {
protected Boolean doInBackground() {
try {
String movieJSONString = getJSONMovies();
String[] ids = parseIdsFromJSON(movieJSONString);
if(ids.lenth != 0) {
FetchMovieReviews moviesReviewsAsyncTask = new FetchMovieReviews();
moviesReviewsAsyncTask.execute(ids);
} else {
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
protected String getJSONMovies() {
//with the code you post, return the json string
}
protected String[] parseIdsFromJSON(String JSON) {
//parse the json and get the ids and return
//return {"1","2","3"}
}
}
public class FetchMovieReviews extends AsyncTask<String[], Void, Void> {
protected Void doInBackground(String[]... params) {
for(String id : params[0]) {
//call the web service and pass the id
}
return null;
}
}
公共类FetchMovieData扩展异步任务{
受保护的布尔值doInBackground(){
试一试{
字符串movieJSONString=getJSONMovies();
String[]ids=parseIdsFromJSON(movieJSONString);
如果(ids.lenth!=0){
FetchMovierViews MoviesReviewAsyncTask=新建FetchMovieReviews();
MoviesReviewAsyncTask.execute(ID);
}否则{
返回false;
}
返回true;
}捕获(例外e){
返回false;
}
}
受保护的字符串getJSONMovies(){
//使用您发布的代码,返回json字符串
}
受保护的字符串[]parseIdsFromJSON(字符串JSON){
//解析json并获取ID并返回
//返回{“1”、“2”、“3”}
}
}
公共类FetchMovieReviews扩展了异步任务{
受保护的Void doInBackground(字符串[]…参数){
for(字符串id:params[0]){
//调用web服务并传递id
}
返回null;
}
}
您可以将用于管理web服务调用的所有功能放在MoviesRESTCalls类中,以及用于管理MoviesJSONParser类或类似的类中的json,代码将更加清晰。因此,我最终使用的是web服务的翻新库。谢谢大家的帮助,让我知道你的想法
public Context mContext;
private MovieJSON mMovieData;
private ReviewJSON mMovieReviews;
private VideoJSON mMovieVideos;
public boolean mSortByMostPopular;
ITaskCompleteListener mTaskCompleteListener;
public FetchMovieData(Context context, boolean sortType, ITaskCompleteListener listener) {
mContext = context;
this.mSortByMostPopular = sortType;
this.mTaskCompleteListener = listener;
}
public void getMovies() {
new FetchMovies().execute();
}
public void getReviews() {
new FetchReviews().execute();
}
public void getVideos() {
new FetchTrailers().execute();
}
private class FetchMovies extends AsyncTask<String, Void, Void > {
@Override
protected Void doInBackground(String... params) {
WebService service = new WebService();
//TODO Re-Implement sorting
mMovieData = service.getMovies();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieData != null)
Constants.mMovies = MovieDataParser.getMovieData(mMovieData);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
}
private class FetchReviews extends AsyncTask<String, Void, Void > {
@Override
protected Void doInBackground(String... params) {
WebService service = new WebService();
mMovieReviews = service.getReviews();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieReviews != null)
Constants.mReviews = MovieDataParser.getReviewData(mMovieReviews);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
}
private class FetchTrailers extends AsyncTask<String, Void, Void > {
@Override
protected Void doInBackground(String... params) {
WebService service = new WebService();
mMovieVideos = service.getVideos();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieVideos != null)
Constants.mTrailers = MovieDataParser.getVideoData(mMovieVideos);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
}
}问题是什么?在列表中添加url,并为每个url执行异步任务。确保你的asynctask序列如果你的列表很大我猜在你的电影活动中,你会显示一个电影列表。当用户单击电影时,您必须在MovieReviewActivity中显示电影评论。因此,在ListView的OnItemClickListener中,您可以启动MovieReviewAsyncTask以获取电影评论。是的,我正在为udacity电影应用程序做第二部分。Android纳米开发者学位:)。好的,我会试试这个谢谢!嗯,好的,我明白了,但是你如何保证第一个doInBackground()将在电影评论doInBackground()之前完成呢。也可以将其放入一个类而不是两个FetchMovieData类中吗?抱歉,第二个异步任务是另一个类“FetchMovieReviews”(编辑错误)。您可以使用布尔值进行管理,检查ids长度是否为零(第一个web服务调用未返回任何内容或json解析中的其他错误),然后您可以处理对其他web服务的调用以获取评论。另外,如果Http连接出现另一个错误,则抛出异常,不处理第二个doInBackground。答案已编辑!
RestAdapter mRetrofit;
MovieDBService mService;
public WebService() {
mRetrofit = new RestAdapter.Builder()
.setEndpoint("http://api.themoviedb.org")
.build();
mService = mRetrofit.create(MovieDBService.class);
}
public MovieJSON getMovies() {
return mService.listMovies("");
}
public ReviewJSON getReviews() {
return mService.listReviews("76341");
}
public VideoJSON getVideos() {
return mService.listVideos("76341");
}