在片段和适配器中使用上下文时出现 NullPointerException
NullPointerException while using context in Fragment and Adapter
我有一个包含片段的导航抽屉。此片段有一个 ViewPager,它附加到 2 个选项卡。这两个选项卡也是 Fragments。
问题是当我在 Navigation Drawer 中的菜单项之间切换时,3-4 次一切正常,但应用程序突然关闭。没有"Unfortunately your app has crashed"的错误。当我检查 phone 上所有打开的应用程序时,该应用程序就在那里。我不知道应用程序处于哪个状态,但我确定它没有最小化,尽管它看起来已经最小化了。一旦发生这种情况,logcat 的输出就会消失。所以我将 logcat 的输出通过管道传输到一个文件,这是我得到的错误:
E/AndroidRuntime(16738): FATAL EXCEPTION: main
E/AndroidRuntime(16738): Process: com.galleri5.android, PID: 16738
E/AndroidRuntime(16738): java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.Application android.support.v7.app.AppCompatActivity.getApplication()' on a null object reference
E/AndroidRuntime(16738): at com.galleri5.android.adapters.UserStudioHiFivesNavigationAdapter.<init>(UserStudioHiFivesNavigationAdapter.java:69)
E/AndroidRuntime(16738): at com.galleri5.android.fragments.ProfileHiFivesNavigationFragment.success(ProfileHiFivesNavigationFragment.java:81)
E/AndroidRuntime(16738): at com.galleri5.android.fragments.ProfileHiFivesNavigationFragment.success(ProfileHiFivesNavigationFragment.java:77)
E/AndroidRuntime(16738): at retrofit.CallbackRunnable.run(CallbackRunnable.java:45)
E/AndroidRuntime(16738): at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime(16738): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime(16738): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(16738): at android.app.ActivityThread.main(ActivityThread.java:5268)
E/AndroidRuntime(16738): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(16738): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(16738): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
E/AndroidRuntime(16738): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
这不是唯一的错误,但所有错误都是此错误的变体,我认为这是因为上下文为空而发生的。
这是我片段的相关部分:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_profile_hi_fives_navigation, container, false);
listView = (ExpandableListView) view.findViewById(R.id.lvExp);
return view;
}
public void showDetails(String galleryId) {
Intent intent = new Intent(getActivity(), UserHiFiveDetailsActivity.class);
intent.putExtra("ID", galleryId);
startActivity(intent);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Galleri5Application application = (Galleri5Application) getActivity().getApplication();
API = application.getAPI();
Tracker mTracker = application.getDefaultTracker();
mTracker.setScreenName("ProfileHiFivesNavigationFragment");
mTracker.send(new HitBuilders.ScreenViewBuilder().build());
RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", "Token " + token);
}
};
OkHttpClient okHttpClient = new OkHttpClient();
RestAdapter restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(API)
.setRequestInterceptor(requestInterceptor)
.build();
StudioHiFivesAPI studioHiFivesAPI = restAdapter.create(StudioHiFivesAPI.class);
studioHiFivesAPI.getFeed(userId, "json", new Callback<List<StudioHiFives>>() {
@Override
public void success(List<StudioHiFives> studioHiFives, Response response) {
Log.i("USER", "HiFives successful");
adapter = new UserStudioHiFivesNavigationAdapter(getActivity(), studioHiFives, ProfileHiFivesNavigationFragment.this);
listView.setAdapter(adapter);
}
@Override
public void failure(RetrofitError error) {
Log.i("USER", "Profile HiFives Fragment Failed");
}
});
}
这是我的适配器的构造函数:
private Context context;
private List<StudioHiFives> list;
private Fragment fragment;
private static LayoutInflater inflater = null;
private Picasso picasso;
Typeface opensans;
String API;
private String token;
private TinyDB tinyDB;
private boolean[] followed;
RequestInterceptor requestInterceptor;
RestAdapter restAdapter;
static int radius = Utils.dpToPx(40);
static int imageSize = Utils.dpToPx(57);
Galleri5Application application;
Tracker mTracker;
public UserStudioHiFivesNavigationAdapter(Context context, List<StudioHiFives> list, Fragment fragment) {
this.context = context;
this.list = list;
this.fragment = fragment;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
opensans = Typeface.createFromAsset(context.getAssets(), "fonts/OpenSans-Regular.ttf");
OkHttpClient okHttpClient = new OkHttpClient();
picasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(okHttpClient))
.build();
application = (Galleri5Application) ((AppCompatActivity)context).getApplication();
API = application.getAPI();
mTracker = application.getDefaultTracker();
tinyDB = new TinyDB(context);
token = tinyDB.getString("Galleri5 Access Token");
requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", "Token " + token);
}
};
restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(API)
.setRequestInterceptor(requestInterceptor)
.build();
followed = new boolean[list.size()];
for(int i=0; i<list.size(); i++) {
followed[i] = list.get(i).isFollowing();
}
}
为什么会出现这些错误,为什么我的应用程序没有完全崩溃?我应该在片段的什么地方编写用于创建视图、初始化上下文和进行网络请求的代码?任何帮助将不胜感激。
找到解决此问题的方法。实际上 getActivity()
正在返回 null
。所以添加了这个检查:
if (isAdded()) {
adapter = new UserStudioHiFivesNavigationAdapter(getActivity(), studioHiFives, ProfileHiFivesNavigationFragment.this);
listView.setAdapter(adapter);
}
onAttach()
方法已弃用。您可以在片段中创建一个 Context 对象。在 onCreateView()
方法中,通过从 getActivity() 获取它来保存您的上下文。现在您已准备好在片段中的任何位置使用此上下文。
private Context mContext;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mContext=getActivity();
View view = inflater.inflate(R.layout.fragment_profile_hi_fives_navigation, container, false);
listView = (ExpandableListView) view.findViewById(R.id.lvExp);
return view;
}
我有一个包含片段的导航抽屉。此片段有一个 ViewPager,它附加到 2 个选项卡。这两个选项卡也是 Fragments。
问题是当我在 Navigation Drawer 中的菜单项之间切换时,3-4 次一切正常,但应用程序突然关闭。没有"Unfortunately your app has crashed"的错误。当我检查 phone 上所有打开的应用程序时,该应用程序就在那里。我不知道应用程序处于哪个状态,但我确定它没有最小化,尽管它看起来已经最小化了。一旦发生这种情况,logcat 的输出就会消失。所以我将 logcat 的输出通过管道传输到一个文件,这是我得到的错误:
E/AndroidRuntime(16738): FATAL EXCEPTION: main
E/AndroidRuntime(16738): Process: com.galleri5.android, PID: 16738
E/AndroidRuntime(16738): java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.Application android.support.v7.app.AppCompatActivity.getApplication()' on a null object reference
E/AndroidRuntime(16738): at com.galleri5.android.adapters.UserStudioHiFivesNavigationAdapter.<init>(UserStudioHiFivesNavigationAdapter.java:69)
E/AndroidRuntime(16738): at com.galleri5.android.fragments.ProfileHiFivesNavigationFragment.success(ProfileHiFivesNavigationFragment.java:81)
E/AndroidRuntime(16738): at com.galleri5.android.fragments.ProfileHiFivesNavigationFragment.success(ProfileHiFivesNavigationFragment.java:77)
E/AndroidRuntime(16738): at retrofit.CallbackRunnable.run(CallbackRunnable.java:45)
E/AndroidRuntime(16738): at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime(16738): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime(16738): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(16738): at android.app.ActivityThread.main(ActivityThread.java:5268)
E/AndroidRuntime(16738): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(16738): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(16738): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
E/AndroidRuntime(16738): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
这不是唯一的错误,但所有错误都是此错误的变体,我认为这是因为上下文为空而发生的。
这是我片段的相关部分:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_profile_hi_fives_navigation, container, false);
listView = (ExpandableListView) view.findViewById(R.id.lvExp);
return view;
}
public void showDetails(String galleryId) {
Intent intent = new Intent(getActivity(), UserHiFiveDetailsActivity.class);
intent.putExtra("ID", galleryId);
startActivity(intent);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Galleri5Application application = (Galleri5Application) getActivity().getApplication();
API = application.getAPI();
Tracker mTracker = application.getDefaultTracker();
mTracker.setScreenName("ProfileHiFivesNavigationFragment");
mTracker.send(new HitBuilders.ScreenViewBuilder().build());
RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", "Token " + token);
}
};
OkHttpClient okHttpClient = new OkHttpClient();
RestAdapter restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(API)
.setRequestInterceptor(requestInterceptor)
.build();
StudioHiFivesAPI studioHiFivesAPI = restAdapter.create(StudioHiFivesAPI.class);
studioHiFivesAPI.getFeed(userId, "json", new Callback<List<StudioHiFives>>() {
@Override
public void success(List<StudioHiFives> studioHiFives, Response response) {
Log.i("USER", "HiFives successful");
adapter = new UserStudioHiFivesNavigationAdapter(getActivity(), studioHiFives, ProfileHiFivesNavigationFragment.this);
listView.setAdapter(adapter);
}
@Override
public void failure(RetrofitError error) {
Log.i("USER", "Profile HiFives Fragment Failed");
}
});
}
这是我的适配器的构造函数:
private Context context;
private List<StudioHiFives> list;
private Fragment fragment;
private static LayoutInflater inflater = null;
private Picasso picasso;
Typeface opensans;
String API;
private String token;
private TinyDB tinyDB;
private boolean[] followed;
RequestInterceptor requestInterceptor;
RestAdapter restAdapter;
static int radius = Utils.dpToPx(40);
static int imageSize = Utils.dpToPx(57);
Galleri5Application application;
Tracker mTracker;
public UserStudioHiFivesNavigationAdapter(Context context, List<StudioHiFives> list, Fragment fragment) {
this.context = context;
this.list = list;
this.fragment = fragment;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
opensans = Typeface.createFromAsset(context.getAssets(), "fonts/OpenSans-Regular.ttf");
OkHttpClient okHttpClient = new OkHttpClient();
picasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(okHttpClient))
.build();
application = (Galleri5Application) ((AppCompatActivity)context).getApplication();
API = application.getAPI();
mTracker = application.getDefaultTracker();
tinyDB = new TinyDB(context);
token = tinyDB.getString("Galleri5 Access Token");
requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", "Token " + token);
}
};
restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(API)
.setRequestInterceptor(requestInterceptor)
.build();
followed = new boolean[list.size()];
for(int i=0; i<list.size(); i++) {
followed[i] = list.get(i).isFollowing();
}
}
为什么会出现这些错误,为什么我的应用程序没有完全崩溃?我应该在片段的什么地方编写用于创建视图、初始化上下文和进行网络请求的代码?任何帮助将不胜感激。
找到解决此问题的方法。实际上 getActivity()
正在返回 null
。所以添加了这个检查:
if (isAdded()) {
adapter = new UserStudioHiFivesNavigationAdapter(getActivity(), studioHiFives, ProfileHiFivesNavigationFragment.this);
listView.setAdapter(adapter);
}
onAttach()
方法已弃用。您可以在片段中创建一个 Context 对象。在 onCreateView()
方法中,通过从 getActivity() 获取它来保存您的上下文。现在您已准备好在片段中的任何位置使用此上下文。
private Context mContext;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mContext=getActivity();
View view = inflater.inflate(R.layout.fragment_profile_hi_fives_navigation, container, false);
listView = (ExpandableListView) view.findViewById(R.id.lvExp);
return view;
}