Java 如何修复空片段?
我是Android开发新手,尝试创建自己的应用程序。它应该使用YouTube数据API显示特定的YouTube频道。我从Android Studio中的标准底部导航模板开始,并使用Github上的以下项目获得一些启动帮助 我不得不在代码中修改一些东西,比如不推荐的http调用,以使其在新的Android APK中运行。从我的角度来看,一切似乎都很好:我可以看到API内容看起来不错,每个标题/描述/发布日期都放在相应的变量中。日志中也没有错误消息。当我启动模拟器时,应用程序运行正常。但是,只要我切换到“Dashboard”片段(代码所在的位置),它就是空的 DashboardFragment.javaJava 如何修复空片段?,java,android,android-fragments,youtube-data-api,Java,Android,Android Fragments,Youtube Data Api,我是Android开发新手,尝试创建自己的应用程序。它应该使用YouTube数据API显示特定的YouTube频道。我从Android Studio中的标准底部导航模板开始,并使用Github上的以下项目获得一些启动帮助 我不得不在代码中修改一些东西,比如不推荐的http调用,以使其在新的Android APK中运行。从我的角度来看,一切似乎都很好:我可以看到API内容看起来不错,每个标题/描述/发布日期都放在相应的变量中。日志中也没有错误消息。当我启动模拟器时,应用程序运行正常。但是,只要我切
public class DashboardFragment extends Fragment {
private static String API_KEY = "hidden"; //normaler API key ohne limits, kein oauth
private static String CHANNEL_ID = "hidden";
private static String CHANNEL_GET_URL = "https://www.googleapis.com/youtube/v3/search?part=snippet&order=date&channelId="+CHANNEL_ID+"&maxResults=20&key="+API_KEY+"";
private RecyclerView mList_videos = null;
private VideoPostAdapter adapter = null;
private ArrayList<YouTubeDataModel> mListData = new ArrayList<>();
public DashboardFragment () {
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
mList_videos = (RecyclerView) view.findViewById(R.id.mList_videos);
initList(mListData);
new RequestYouTubeAPI().execute();
return view;
}
private void initList(ArrayList<YouTubeDataModel> mListData) {
mList_videos.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new VideoPostAdapter(getActivity(), mListData);
mList_videos.setAdapter(adapter);
}
// create asynctask to get data from youtube
private class RequestYouTubeAPI extends AsyncTask<Void, String, String>{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Void... params) {
URL url = null;
String json = null;
StringBuffer sb = new StringBuffer();
try {
url = new URL(CHANNEL_GET_URL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
//HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
HttpURLConnection urlConnection = NetCipher.getHttpsURLConnection(url);
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String inputLine = "";
while ((inputLine = br.readLine()) != null) {
sb.append(inputLine);
}
json = sb.toString();
return json;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if(response != null){
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
public ArrayList<YouTubeDataModel> parseVideoListFromResponse(JSONObject jsonObject) {
ArrayList<YouTubeDataModel> mList = new ArrayList<>();
if (jsonObject.has("items")) {
try {
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
if (json.has("id")) {
JSONObject jsonID = json.getJSONObject("id");
String video_id = "";
if (jsonID.has("videoId")) {
video_id = jsonID.getString("videoId");
}
if (jsonID.has("kind")) {
if (jsonID.getString("kind").equals("youtube#video")) {
YouTubeDataModel youtubeObject = new YouTubeDataModel();
JSONObject jsonSnippet = json.getJSONObject("snippet");
String title = jsonSnippet.getString("title");
String description = jsonSnippet.getString("description");
String publishedAt = jsonSnippet.getString("publishedAt");
String thumbnail = jsonSnippet.getJSONObject("thumbnails").getJSONObject("high").getString("url");
youtubeObject.setTitle(title);
youtubeObject.setDescription(description);
youtubeObject.setPublishedAt(publishedAt);
youtubeObject.setThumbnail(thumbnail);
youtubeObject.setVideo_id(video_id);
mList.add(youtubeObject);
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return mList;
}
}
youtube_post_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ImageView
android:id="@+id/ImageThumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"/>
<TextView
android:id="@+id/textViewDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="published at"
android:singleLine="true"
android:layout_alignParentRight="true"
android:layout_margin="5dp"
android:textColor="@android:color/white"
android:textSize="12dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="video Title"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="22dp"/>
<TextView
android:id="@+id/textViewDes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="video description"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="12dp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
fragment_dashboard.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mList_videos"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
不幸的是,我不知道为什么碎片仍然是空的。在Android Studio日志中没有任何错误,我真的希望您能帮助我:/在您的
RequestYouTubeAPI
ASyncTask
中,您有以下错误代码:
} catch (IOException e) {
e.printStackTrace();
return null;
}
然后在onPostExecute
中,您有以下内容:
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if(response != null){
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
因此,如果您得到一个错误,返回null
,如果onPostExecute
得到一个null
响应,那么它什么也不做
所以这一个地方你可能有一个错误,因此是一个空白片段
在解决此问题之前,您可以证明这是这样发生的:
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if(response == null){
Log.e("TUT", "We did not get a response, not updating the UI.");
} else {
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
您可以通过两种方式解决此问题: 在
doInBackground
中,将捕获更改为:
} catch (IOException e) {
Log.e("TUT", "error", e);
// Change this JSON to match what the parse expects, so you can show an error on the UI
return "{\"yourJson\":\"error!\"}";
}
或onPostExecute
:
if(response == null){
List errorList = new ArrayList();
// Change this data model to show an error case to the UI
errorList.add(new YouTubeDataModel("Error");
mListData = errorList;
initList(mListData);
} else {
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
希望这会有所帮助,代码中可能还有其他错误,但如果API、Json、授权、,互联网等。首先检查json响应如果响应为空,则在将mListData传递给adpter print in Log之前不显示recyclerview。我猜问题在于parseVideoListFromResponse,请尝试验证您是否实际到达parseVideoListFromResponse调用,然后验证它是否正确地找到了节点,如果(jsonObject.has(“items”))为false,这将解释该列表为空,我将突出显示该列表作为答案,因为它是本例中最有用的一个。我发现了调试器的错误,但是你的想法把我推向了正确的方向。最后,我在代码中混淆了mList和mListData。很抱歉我的回复太晚了,谢谢大家的快速反馈。这是我在这里的第一个问题,我真的很惊讶!
} catch (IOException e) {
Log.e("TUT", "error", e);
// Change this JSON to match what the parse expects, so you can show an error on the UI
return "{\"yourJson\":\"error!\"}";
}
if(response == null){
List errorList = new ArrayList();
// Change this data model to show an error case to the UI
errorList.add(new YouTubeDataModel("Error");
mListData = errorList;
initList(mListData);
} else {
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}