在Fragment和Adapter中使用上下文时出现NullPointerException

时间:2015-12-09 07:26:03

标签: android android-fragments android-context android-navigation-drawer

我有一个包含片段的导航抽屉。该片段有一个ViewPager,它附加到2个选项卡。这两个标签也都是碎片。

问题是当我在导航抽屉中的菜单项之间切换时,3-4次一切正常,但随后突然关闭应用程序。没有错误"不幸的是你的应用程序崩溃了#34;。当我检查手机上的所有打开的应用程序时,应用程序就在那里。我不知道该应用程序的状态,但我确信它没有最小化,尽管它看起来已经被最小化了。一旦发生这种情况,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$2.success(ProfileHiFivesNavigationFragment.java:81)
E/AndroidRuntime(16738):    at com.galleri5.android.fragments.ProfileHiFivesNavigationFragment$2.success(ProfileHiFivesNavigationFragment.java:77)
E/AndroidRuntime(16738):    at retrofit.CallbackRunnable$1.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)

这不是唯一的错误,但所有错误都是这个的一点变化,我认为这是因为Context是null。

以下是我片段的相关部分:

@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();
        }
    }

为什么会出现这些错误,为什么我的应用程序不会完全崩溃?我应该在片段中的哪个位置编写用于创建视图,初始化上下文和执行网络请求的代码?任何帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:3)

不推荐使用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;
        }