AsyncTask - 缺少一些东西

时间:2018-03-21 17:29:07

标签: java android android-recyclerview android-asynctask

我正在做一些项目而且我被困了......我做错了什么,可能是用AsyncTask而我不知道要修复什么以及如何...有代码我现在有。

ReviewData.class

public class ReviewData implements Parcelable {

private String mAuthor, mContent;

public ReviewData(String author, String content) {
    this.mAuthor = author;
    this.mContent = content;
}

private ReviewData(Parcel in) {
    mAuthor = in.readString();
    mContent = in.readString();
}

public static final Creator<ReviewData> CREATOR = new Creator<ReviewData>() {
    @Override
    public ReviewData createFromParcel(Parcel in) {
        return new ReviewData(in);
    }

    @Override
    public ReviewData[] newArray(int size) {
        return new ReviewData[size];
    }
};

//Getter method for review author
public String getAuthor() {
    return mAuthor;
}

//Setter method for review author
public void setAuthor(String author) {
    this.mAuthor = author;
}

//Getter method for review content
public String getContent() {
    return mContent;
}

//Setter method for review content
public void setContent(String content) {
    this.mContent = content;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(mAuthor);
    dest.writeString(mContent);
}

}

ReviewAdapter.class

public class ReviewAdapter extends RecyclerView.Adapter<ReviewAdapter.ReviewViewHolder> {

private ArrayList<ReviewData> mReviewList;
private Context mContext;

public ReviewAdapter(Context context, ArrayList<ReviewData> reviewList) {
    this.mContext = context;
    this.mReviewList = reviewList;
}

@Override
public ReviewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    mContext = parent.getContext();
    View view = LayoutInflater.from(mContext).inflate(R.layout.review_item_list,
            parent, false);
    view.setFocusable(true);
    return new ReviewViewHolder(view);
}

@Override
public void onBindViewHolder(final ReviewViewHolder holder, int position) {
    if(mReviewList != null) {
        ReviewData reviewData = mReviewList.get(position);
        holder.reviewAuthor.setText(reviewData.getAuthor());
        holder.reviewContent.setText(reviewData.getContent());
    }
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemCount() {
    if(mReviewList == null) {
        return  0;
    } else {
        return mReviewList.size();
    }
}

public void setReviewList(ArrayList<ReviewData> reviewList) {
    if(reviewList != null) {
        mReviewList = new ArrayList<>(reviewList);
    }
    notifyDataSetChanged();
}

public class ReviewViewHolder extends RecyclerView.ViewHolder {

    TextView reviewAuthor;
    TextView reviewContent;

    public ReviewViewHolder(View itemView) {
        super(itemView);
        reviewAuthor = itemView.findViewById(R.id.review_author);
        reviewContent = itemView.findViewById(R.id.review_content);
    }
}

}

NetworkUtils.class(但只有Review url构建器的代码,其他东西完美无缺)。 PS。这个解析是作为API文档写的......它应该是someurl / movie / {id} / reviews

//URL builder for reviews
public static URL buildReviewUrl(String id) {
    Uri builtUri = Uri.parse(BASE_MOVIE_URL + id + REVIEW).buildUpon()
            .appendQueryParameter(QUERY_API_KEY, API_KEY)
            .build();

    URL url = null;
    try {
        url = new URL(builtUri.toString());
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

    return url;
}

JsonData。课程(也是,仅适用于评论,其他作品完美...)

//JSON for Review
public static ArrayList<ReviewData> getReviewFromJson(String json) throws JSONException {
    ArrayList<ReviewData> listOfReviews = new ArrayList<>();

    try {
        JSONObject reviews = new JSONObject(json);
        JSONArray reviewsArray = reviews.getJSONArray(QUERY_RESULTS);
        for(int i = 0; i < reviewsArray.length(); i++) {
            JSONObject jsonReview = reviewsArray.getJSONObject(i);
            String author = jsonReview.optString(REVIEW_AUTHOR);
            String content = jsonReview.optString(REVIEW_CONTENT);

            ReviewData reviewData = new ReviewData(author, content);

            listOfReviews.add(reviewData);
        }
    } catch(JSONException e) {
        e.printStackTrace();
        Log.e("ReviewJson", "JSON Review Error");
    }

    return listOfReviews;
}

ReviewAsyncTask.class

public class ReviewAsyncTask extends AsyncTask<String, Void, ArrayList<ReviewData>> {

private ReviewData mReviewData;

public interface ReviewResponse {
    void finished(ArrayList<ReviewData> output);
}

private ReviewResponse reviewResponse = null;

public ReviewAsyncTask(ReviewResponse reviewResponse) {
    this.reviewResponse = reviewResponse;
}

@Override
protected ArrayList<ReviewData> doInBackground(String... strings) {
    String rawData = "";
    ArrayList<ReviewData> reviewList = new ArrayList<>();
    try {
        rawData = NetworkUtils.getResponseFromHttpRequest(NetworkUtils
                .buildReviewUrl(String.valueOf(mReviewData)));
        reviewList = JsonData.getReviewFromJson(rawData);
    } catch (IOException e) {
        e.printStackTrace();
        Log.e("ReviewAsyncTask", "Error in ReviewAsyncTask");
    } catch (JSONException e) {
        e.printStackTrace();
        Log.e("JSONAsync", "JSON problem");
    }

    return reviewList;
}

@Override
protected void onPostExecute(ArrayList<ReviewData> reviewData) {
    reviewResponse.finished(reviewData);

}

}

和MovieDetails活动(除了评论回收评论到下一评论外,一切正常。

public class MovieDetails extends AppCompatActivity implements ReviewAsyncTask.ReviewResponse {

private final static String BASE_URL = "http://image.tmdb.org/t/p/";
private final static String SIZE = "w185/";

private ArrayList<ReviewData> mReviewList;

private ReviewAdapter mReviewAdapter;

@BindView(R.id.poster_detail)
ImageView mMoviePoster;
@BindView(R.id.title_detail)
TextView mMovieTitle;
@BindView(R.id.release_date)
TextView mReleaseDate;
@BindView(R.id.average_vote)
TextView mAverageVote;
@BindView(R.id.synopsis)
TextView mSynopsis;

@BindView(R.id.review_recycler)
RecyclerView mReviewRecycle;

Context mContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_movie_details);
    ButterKnife.bind(this);

    displayMovieDetail();

    //Review RecycleView
    mReviewList = new ArrayList<>();
    mReviewAdapter = new ReviewAdapter(this, mReviewList);

    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
    mReviewRecycle.setLayoutManager(layoutManager);
    mReviewRecycle.setHasFixedSize(true);
    mReviewRecycle.setAdapter(mReviewAdapter);
}

@Override
public void finished(ArrayList<ReviewData> output) {
    ReviewAsyncTask reviewAsyncTask = new ReviewAsyncTask(this);
    reviewAsyncTask.execute();
}

/* Method for displaying the info about movies in activity details
 * @param mMoviePoster sets the movie poster
 * @param mMovieTitle sets original title of the movie
 * @param mReleaseDate sets release date of the movie
 * @param mAverageVote sets average rating grade of the movie
 * @param mSynopsis sets plot of the movie */
private void displayMovieDetail() {
    int idMovie = (Integer) getIntent().getExtras().get(getString(R.string.movie_id));

    List<MovieData> movieList;
    movieList = getIntent().getParcelableArrayListExtra(getString(R.string.movie_lsit));

    MovieData movieData = movieList.get(idMovie);

    Picasso.with(mContext).load(BASE_URL + SIZE +
            movieData.getPoster()).into(mMoviePoster);
    mMovieTitle.setText(movieData.getTitle());
    mReleaseDate.setText(movieData.getReleaseDate());
    mAverageVote.setText(Double.toString(movieData.getRating()));
    mSynopsis.setText(movieData.getSynopsis());
}

}

P.S。我会分享github链接,但我应该给你我个人的API密钥。 :(

2 个答案:

答案 0 :(得分:1)

您需要在AsyncTask中启动onCreate()(就像之前一样),然后在finished()中获取结果并将其添加到适配器的数据列表中。 最后,不要忘记致电notifyDatasetChanged()

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_movie_details);
    // skipping some lines of code here...
    mReviewRecycle.setAdapter(mReviewAdapter);
    ReviewAsyncTask reviewAsyncTask = new ReviewAsyncTask(this);
    reviewAsyncTask.execute();
}

@Override
public void finished(ArrayList<ReviewData> output) {
    mReviewList.addAll(output);
    mReviewAdapter.notifyDatasetChanged();
}

(请注意,为简洁起见,我跳过了空检查和错误处理)

答案 1 :(得分:0)

  1. 在MovieDetails onCreate中检索当前的电影ID,就像在displayMovieDetail中一样。
  2. 将该ID发送给ReviewAsyncTask(您需要修改ReviewAsyncTask的构造函数)
  3. 在ReviewAsyncTask中检索id,将其保存为成员变量,然后在doInBackground方法中将该id作为参数发送给buildReviewUrl。