java - 调用 setAdapter(cursorAdapter) 方法时应用程序崩溃
问题描述
我正在尝试创建一个应用程序,它可以使用片段根据指定的搜索字符串显示联系人列表。但该应用程序似乎在布局绘制期间崩溃,没有做任何事情或显示任何内容。
ContactsFragment.java 的代码:
package com.example.contacts;
import ...
public class ContactsFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>,
AdapterView.OnItemClickListener {
@SuppressLint("InlinedApi")
private final static String[] FROM_COLUMNS = {
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
};
private final static int[] TO_IDS = {
android.R.id.text1
};
ListView contactsList;
long contactID;
String contactKey;
Uri contactURI;
public ContactsFragment(){}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.contact_list, container, false);
}
SimpleCursorAdapter cursorAdapter;
@SuppressLint("ResourceType")
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
contactsList = Objects.requireNonNull(getActivity()).findViewById(R.id.contact_list);
cursorAdapter = new SimpleCursorAdapter(getActivity(),
R.layout.contact_list_item,
null,
FROM_COLUMNS,
TO_IDS,
0);
contactsList.setAdapter(cursorAdapter); //THROWS NULL POINTER EXCEPTION
contactsList.setOnItemClickListener(this);
}
@SuppressLint("InlinedApi")
private static final String[] PROJECTION =
{
ContactsContract.Contacts._ID,
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
};
private static final int CONTACT_ID_INDEX = 0;
private static final int CONTACT_KEY_INDEX = 1;
@SuppressLint("InlinedApi")
private static final String SELECTION = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " LIKE ?";
private String searchString="";
private String[] selectionArgs = { searchString };
@Override
public void onItemClick(AdapterView<?> parent, View item, int position, long rowID) {
Cursor cursor = ((CursorAdapter)(parent.getAdapter())).getCursor();
cursor.moveToPosition(position);
contactID = cursor.getLong(CONTACT_ID_INDEX);
contactKey = cursor.getString(CONTACT_KEY_INDEX);
contactURI = ContactsContract.Contacts.getLookupUri(contactID, contactKey);
/*
* You can use contactUri as the content URI for retrieving
* the details for a contact.
*/
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LoaderManager.getInstance(this).initLoader(0, null, this);
}
@NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
/*
* Makes search string into pattern and
* stores it in the selection array
*/
selectionArgs[0] = "%" + searchString + "%";
// Starts the query
return new CursorLoader(
Objects.requireNonNull(getActivity()),
ContactsContract.Contacts.CONTENT_URI,
PROJECTION,
SELECTION,
selectionArgs,
null
);
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) {
cursorAdapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
cursorAdapter.swapCursor(null);
}
}
错误出现在引发. 我还没有创建搜索小部件,因为我无法正确解析布局和链接。contactsList.setAdapter(cursorAdapter);
NullPointerException
还有MainActivity.java
文件:
package com.example.contacts;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
我附上activity_main.xml
供参考:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<fragment
android:id="@+id/contact_view"
android:name="com.example.contacts.ContactsFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
我为片段布局使用了两个文件——contact_list.xml
它们contact_list_item.xml
分别是:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contact_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true" />
这个想法是片段将有一个ListView
包含单个项目的TextView
.
我已经提到该应用程序在应用程序的清单文件中使用联系人权限。
以下是崩溃日志:
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.contacts, PID: 25682
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.contacts/com.example.contacts.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.contacts.ContactsFragment.onActivityCreated(ContactsFragment.java:56)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2619)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:904)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
at android.app.Activity.performStart(Activity.java:6683)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2687)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
I/art: Enter while loop.
如果有人可以帮助我,我将不胜感激,因为我对 Android 编程很陌生。
解决方案
该错误NullPointerException
是由于代码试图访问(或绑定)到尚未使用的 id 的事实。
其中给出的idfindViewById
应该R.id.contact_list_view
是R.id.contact_list
推荐阅读
- c# - WPF 子菜单项不显示在顶层菜单项下
- r - 如何用另一行中的单词替换一行中的部分字符串?
- laravel - 如何为 3D 打印机生成仅可打印的链接,而不是模型的可下载链接?
- swift - Xcode 11 Beta 4 Archive swift 错误
- php - 同一页面上的联系表格
- google-apps-script - 取消共享 Google Drive 上的所有文件、文件夹和子文件夹
- python - 如何使用 Python 和 ElementTree 挖掘 XML 文件中的字段数据
- excel - 编辑多个单元格进行超链接,无需一一进行
- c# - C# LINQ 从具有多个字段的列表中选择表
- javascript - 如何检查组件的 props 的组件类型?