我将结束本教程,在Android中构建一个简单的YouTube应用程序,所有代码都在这里。
我没有修改代码,但是在将VideoItem
ArrayAdapter
设置为ListView
时出现空指针异常。(当按"完成"在YouTube上搜索视频时会发生这种情况)
我能找到的唯一类似错误涉及没有在getView()
中将视图设置为正确的片段,这里似乎不是这种情况。是的,我已经用我的密钥更新了YoutubeConnector中的KEY.java。感谢您的任何帮助。
这是日志猫:
04-21 18:26:27.125 24940-24940/com.hathi.simpleplayer E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.hathi.simpleplayer, PID: 24940
java.lang.NullPointerException
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
at android.widget.ListView.setAdapter(ListView.java:486)
at com.hathi.simpleplayer.SearchActivity.updateVideosFound(SearchActivity.java:104)
at com.hathi.simpleplayer.SearchActivity.access$200(SearchActivity.java:22)
at com.hathi.simpleplayer.SearchActivity$3$1.run(SearchActivity.java:77)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
这是发生错误的类(在最后一行):
public class SearchActivity extends Activity {
private EditText searchInput;
private ListView videosFound;
private Handler handler;
private List<VideoItem> searchResults;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
searchInput = (EditText)findViewById(R.id.search_input);
videosFound = (ListView)findViewById(R.id.videos_found);
handler = new Handler();
addClickListener();
searchInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE){
searchOnYoutube(v.getText().toString());
return false;
}
return true;
}
});
}
private void addClickListener(){
videosFound.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int pos,
long id) {
Intent intent = new Intent(getApplicationContext(), PlayerActivity.class);
intent.putExtra("VIDEO_ID", searchResults.get(pos).getId());
startActivity(intent);
}
});
}
private void searchOnYoutube(final String keywords){
new Thread(){
public void run(){
YoutubeConnector yc = new YoutubeConnector(SearchActivity.this);
searchResults = yc.search(keywords);
handler.post(new Runnable(){
public void run(){
updateVideosFound();
}
});
}
}.start();
}
private void updateVideosFound(){
ArrayAdapter<VideoItem> adapter = new ArrayAdapter<VideoItem>(getApplicationContext(), R.layout.video_item, searchResults){
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = getLayoutInflater().inflate(R.layout.video_item, parent, false);
}
ImageView thumbnail = (ImageView)convertView.findViewById(R.id.video_thumbnail);
TextView title = (TextView)convertView.findViewById(R.id.video_title);
TextView description = (TextView)convertView.findViewById(R.id.video_description);
VideoItem searchResult = searchResults.get(position);
Picasso.with(getApplicationContext()).load(searchResult.getThumbnailURL()).into(thumbnail);
title.setText(searchResult.getTitle());
description.setText(searchResult.getDescription());
return convertView;
}
};
videosFound.setAdapter(adapter);
}
video_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
>
<ImageView
android:id="@+id/video_thumbnail"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="20dp"
/>
<TextView android:id="@+id/video_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/video_thumbnail"
android:layout_alignParentTop="true"
android:layout_marginTop="5dp"
android:textSize="25sp"
android:textStyle="bold"
/>
<TextView android:id="@+id/video_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/video_thumbnail"
android:layout_below="@+id/video_title"
android:textSize="15sp"
/>
</RelativeLayout>
activity_search.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/search"
android:id="@+id/search_input"
android:singleLine="true"
/>
<ListView
android:id="@+id/videos_found"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="5dp"
/>
</LinearLayout>
它发生在你的守卫身上。在 proguard 文件中保留必要的类。
minifyEnabled false
这在你构建.gradle文件中就足够了