设置 ListAdapter 时 Android Java 应用程序崩溃
Posted
技术标签:
【中文标题】设置 ListAdapter 时 Android Java 应用程序崩溃【英文标题】:Android Java App crashed when setting up ListAdapter 【发布时间】:2016-05-05 05:45:34 【问题描述】:当我尝试将我的适配器链接到 ListView 时,我的 android 应用程序崩溃了
这是我的活动
package needforbleed.com.music;
import android.content.Context;
import android.provider.MediaStore;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.net.Uri;
import android.content.ContentResolver;
import android.database.Cursor;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
//vars
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
public ArrayList<Song> songList;
private ListView songView;
//methods
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
);
songList=new ArrayList<Song>();
songView = (ListView)findViewById(R.id.lv_titles);
getSongList();
Collections.sort(songList, new Comparator<Song>()
public int compare(Song a, Song b)
return a.getName().compareTo(b.getName());
);
SongAdapter songAdt = new SongAdapter(this,R.id.lv_titles, songList);
songView.setAdapter(songAdt);
/* for(int x=0;x<songList.size();x++)
Toast toast = Toast.makeText(this,songList.get(x).getName(),Toast.LENGTH_SHORT);
toast.show();
*///I used that loop to check songList for Content. It has content so that's not the error.
public class SectionsPagerAdapter extends FragmentPagerAdapter
public SectionsPagerAdapter(FragmentManager fm)
super(fm);
@Override
public Fragment getItem(int position)
switch (position)
case 0:return Player.newInstance(0,"Player");
case 1:return Artists.newInstance(1,"Artists");
case 2:return Albums.newInstance(2,"Albums");
case 3:return Titles.newInstance(3,"Titles");
return null;
@Override
public int getCount()
// Show 3 total pages.
return 4;
@Override
public CharSequence getPageTitle(int position)
switch (position)
case 0:
return "Player";
case 1:
return "Artists";
case 2:
return "Albums";
case 3:
return "Titles";
return null;
public void getSongList()
ContentResolver musicResolver = getContentResolver();
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
if(musicCursor!=null && musicCursor.moveToFirst())
//get columns
int titleColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ARTIST);
int albumColumn=musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM);
//add songs to list
do
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
String thisAlbum = musicCursor.getString(albumColumn);
Song s=new Song();
s.setID(thisId);
s.setName(thisTitle);
s.setArtist(thisArtist);
s.setAlbum(thisAlbum);
songList.add(s);
while (musicCursor.moveToNext());
这是我的自定义 ListAdapter
package needforbleed.com.music;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Created on 27.01.2016.
*/
public class SongAdapter extends ArrayAdapter<Song>
public SongAdapter(Context context, int textViewResourceId)
super(context, textViewResourceId);
public SongAdapter(Context context, int resource, ArrayList<Song> tracks)
super(context, resource, tracks);
@Override
public View getView(int position, View convertView, ViewGroup parent)
View v = convertView;
if (v == null)
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.title_list,null);
Song p = getItem(position);
if (p != null)
TextView tt1 = (TextView) v.findViewById(R.id.song_title);
TextView tt2 = (TextView) v.findViewById(R.id.song_artist);
TextView tt3 = (TextView) v.findViewById(R.id.song_album);
if (tt1 != null)
tt1.setText(p.getName());
if (tt2 != null)
tt2.setText(p.getArtist());
if (tt3 != null)
tt3.setText(p.getAlbum());
return v;
这是包含 listView 的 XML 文件:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context="needforbleed.com.music.Titles">
<!-- TODO: Update blank fragment layout -->
<ListView
android:layout_
android:layout_
android:id="@+id/lv_titles"
android:layout_gravity="left|top" />
</FrameLayout>
我出来的错误是:
01-28 02:41:46.635 24445-24445/needforbleed.com.music E/AndroidRuntime: 致命异常: main 进程:needforbleed.com.music,PID:24445 java.lang.RuntimeException:无法启动活动 组件信息needforbleed.com.music/needforbleed.com.music.MainActivity: java.lang.NullPointerException:尝试调用虚拟方法'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' 空对象引用 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2411) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474) 在 android.app.ActivityThread.access$800(ActivityThread.java:144) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:155) 在 android.app.ActivityThread.main(ActivityThread.java:5696) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824) 引起:java.lang.NullPointerException:尝试调用虚拟 方法'无效 android.widget.ListView.setAdapter(android.widget.ListAdapter)' 空对象引用 在 needforbleed.com.music.MainActivity.onCreate(MainActivity.java:92) 在 android.app.Activity.performCreate(Activity.java:5958) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474) 在 android.app.ActivityThread.access$800(ActivityThread.java:144) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:155) 在 android.app.ActivityThread.main(ActivityThread.java:5696) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
我真的不知道那里的 null 是什么。 我什至尝试了这里的解决方案,但无论我遵循什么教程,我都会遇到同样的错误。
【问题讨论】:
我猜没有。我在以下位置引用了它:“songView = (ListView)findViewById(R.id.lv_titles);”但是你知道检查的方法吗? 你确定getSongList
函数在你初始化适配器之前完成并返回值吗??
确实如此。如果我删除了 adepter 的beeing 链接的行,它工作正常。还是我误解了你的问题?
@Needforbleed 可能是 id 拼写错误?您可以检查它是否与 xml 布局中的列表视图 ID 匹配吗?您可以添加日志以查看 songView
是否为空。我认为songView
为空的原因是因为它是唯一适合您的堆栈跟踪的地方,Android.widget.ListView.setAdapter 上的 NPE。
id 是对的。但无论如何我都会检查一下
【参考方案1】:
SongAdapter songAdt = new SongAdapter(this,R.id.lv_titles, songList);
songView.setAdapter(songAdt);
应该是
SongAdapter songAdt = new SongAdapter(this,R.layout.layoutId, songList);
songView.setAdapter(songAdt);
其中 layoutId 是布局文件的资源 ID,其中包含在实例化视图时使用的 TextView。
您可以通过使用“android.R.layout.simple_list_item_1”作为layoutId来使用android提供的默认listitem布局
【讨论】:
以上是关于设置 ListAdapter 时 Android Java 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
从android eclipse中的片段刷新或更新listadapter
使用 ListAdapter 将项目添加到 ListView
在 Fragment 中设置一个新的 ListAdapter
Android:尝试在空对象引用上调用虚拟方法“void android.widget.ListView.setAdapter(android.widget.ListAdapter)”
重复条目:android / support / v7 / recyclerview / extensions / ListAdapter.class [复制]