我正在尝试为youtube频道创建应用,并希望在recyclerview中显示视频列表。我正在使用YoutubeData API v3。我得到一个JSON字符串响应作为我的查询的回报,我手动解析它。
我创建了一个名为Video的类,用于存储有关对象中视频的信息,然后将其添加到ArrayList以传递给recyclerview适配器。最初它工作正常,但随着我想传递给Video对象的细节数量增加,recyclerview停止工作。它只显示最新的两个视频,其余视频不显示。
只要我将videoId传递给适配器,回收站视图就会停止工作。我尝试使用AsyncTask在单独的线程上解析json,但它不起作用。我长期陷入这个错误,无法找出原因。请帮忙!!
这是我的代码:
MainActivity.java:
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
URL url = null;
String resultString = null;
RecyclerView rv;
VideoAdapter adapter;
ArrayList<Video> titles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv = (RecyclerView) findViewById(R.id.rv_display);
url = NetworkUtils.buildUrlFromUsername(Config.FOR_USERNAME);
Log.i("ayusch", "url = " + url);
new YoutubeQueryTask().execute(url);
Log.i("ayusch", "After task");
}
public void formatJSON(String resultString) {
new JSONParseTask().execute(resultString);
}
public class YoutubeQueryTask extends AsyncTask<URL, Void, String> {
@Override
protected String doInBackground(URL... params) {
URL builtUrl = params[0];
resultString = "no result";
try {
resultString = NetworkUtils.getResponseFromUrl(builtUrl);
} catch (IOException e) {
e.printStackTrace();
}
return resultString;
}
@Override
protected void onPostExecute(String s) {
formatJSON(s);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
rv.setLayoutManager(layoutManager);
rv.setHasFixedSize(true);
adapter = new VideoAdapter(titles);
rv.setAdapter(adapter);
}
}
public class JSONParseTask extends AsyncTask<String,Void,String>{
@Override
protected String doInBackground(String... params) {
JSONObject itemsObj, thumbnailsObject, defaultObject, obj, snippetObj;
ArrayList<Video> videoTitles = new ArrayList<>();
String title, thumbnailUrl, description, videoId;
try {
itemsObj = new JSONObject(resultString);
JSONArray itemsArray = itemsObj.getJSONArray("items");
for (int i = 0; i < itemsArray.length(); i++) {
obj = itemsArray.getJSONObject(i);
snippetObj = obj.getJSONObject("snippet");
title = snippetObj.getString("title");
thumbnailsObject = snippetObj.getJSONObject("thumbnails");
defaultObject = thumbnailsObject.getJSONObject("default");
thumbnailUrl = defaultObject.getString("url");
description = snippetObj.getString("description");
videoId = (obj.getJSONObject("id")).getString("videoId");
videoTitles.add(new Video(title, thumbnailUrl, description,videoId));
Log.i("ayusch", "length of array = " + i);
}
} catch (Exception e) {
e.printStackTrace();
}
titles=videoTitles;
return null;
}
}
}
VideoAdapter.java:
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.CustomHolder> {
private int maxNumItems = 25;
ArrayList<Video> titles;
public VideoAdapter(ArrayList<Video> titles) {
this.titles = titles;
}
@Override
public CustomHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
CustomHolder holder = new CustomHolder(root, parent.getContext());
return holder;
}
@Override
public void onBindViewHolder(CustomHolder holder, int position) {
holder.tv_title.setText((titles.get(position).title));
String url = titles.get(position).thumbnailUrl;
Picasso.with(holder.tv_title.getContext()).load(url).into(holder.iv_thumbnail);
holder.tv_description.setText((titles.get(position)).description);
}
@Override
public int getItemCount() {
return titles.size();
}
public class CustomHolder extends RecyclerView.ViewHolder {
TextView tv_title,tv_description;
ImageView iv_thumbnail;
Context c;
public CustomHolder(View itemView, Context context) {
super(itemView);
tv_title = (TextView) itemView.findViewById(R.id.tv_video_title);
iv_thumbnail = (ImageView) itemView.findViewById(R.id.iv_video_thumbnail);
tv_description = (TextView) itemView.findViewById(R.id.tv_video_description);
c = context;
}
}
}
Video.java:
public class Video {
String title;
String thumbnailUrl;
String description;
String videoId;
Video(String vidTitle, String url, String desc, String vidId) {
title = vidTitle;
thumbnailUrl = url;
description = desc;
videoId = vidId;
}
}
另外,请随意为性能建议任何代码改进。我仍处于学习阶段,想要编写出色的性能代码,这个应用程序需要一段时间才能在recyclerview中加载json响应。
答案 0 :(得分:0)
1。执行titles
ArrayList initialization
并从adapter
方法设置RecyclerView onCreate()
。
2。从titles
清除JSONParseTask
列表。
3。将Video
个对象添加到列表titles
而不是videoTitles
。
4。在将每个项目添加到adapter.notifyDataSetChanged()
列表后,请致电RecyclerView
更新titles
。
更新MainActivity
,如下所示:
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
URL url = null;
String resultString = null;
RecyclerView rv;
VideoAdapter adapter;
ArrayList<Video> titles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv = (RecyclerView) findViewById(R.id.rv_display);
url = NetworkUtils.buildUrlFromUsername(Config.FOR_USERNAME);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
rv.setLayoutManager(layoutManager);
rv.setHasFixedSize(true);
titles = new ArrayList<Video>();
adapter = new VideoAdapter(titles);
rv.setAdapter(adapter);
Log.i("ayusch", "url = " + url);
new YoutubeQueryTask().execute(url);
Log.i("ayusch", "After task");
}
public void formatJSON(String resultString) {
new JSONParseTask().execute(resultString);
}
public class YoutubeQueryTask extends AsyncTask<URL, Void, String> {
@Override
protected String doInBackground(URL... params) {
URL builtUrl = params[0];
resultString = "no result";
try {
resultString = NetworkUtils.getResponseFromUrl(builtUrl);
} catch (IOException e) {
e.printStackTrace();
}
return resultString;
}
@Override
protected void onPostExecute(String s) {
formatJSON(s);
}
}
public class JSONParseTask extends AsyncTask<String,Void,String>{
@Override
protected String doInBackground(String... params) {
JSONObject itemsObj, thumbnailsObject, defaultObject, obj, snippetObj;
String title, thumbnailUrl, description, videoId;
try {
itemsObj = new JSONObject(resultString);
JSONArray itemsArray = itemsObj.getJSONArray("items");
// Required to clear list
if (itemsArray.length() > 0)
titles.clear();
for (int i = 0; i < itemsArray.length(); i++) {
obj = itemsArray.getJSONObject(i);
snippetObj = obj.getJSONObject("snippet");
title = snippetObj.getString("title");
thumbnailsObject = snippetObj.getJSONObject("thumbnails");
defaultObject = thumbnailsObject.getJSONObject("default");
thumbnailUrl = defaultObject.getString("url");
description = snippetObj.getString("description");
videoId = (obj.getJSONObject("id")).getString("videoId");
// Add to list
titles.add(new Video(title, thumbnailUrl, description,videoId));
// Update RecyclerView
adapter.notifyDataSetChanged();
Log.i("ayusch", "length of array = " + i);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}
希望这会有所帮助〜
答案 1 :(得分:0)
如果您想简化简单REST调用的代码。您可以使用此库Android RESTAdapter
使用和减少代码非常简单。