Android系统。片段getActivity()有时会返回null [英] Android. Fragment getActivity() sometime returns null

查看:144
本文介绍了Android系统。片段getActivity()有时会返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在开发者控制台错误报告有时我看到NPE问题的报告。我不明白什么是错我的code。在仿真器和我的设备应用程序的工作原理没有forcecloses不错,但有些用户得到NullPointerException异常的片段上课的时候​​调用getActivity()方法。

In developer console error reports sometime I see reports with NPE issue. I not understand what is wrong with my code. On emulator and my device application works good without forcecloses, however some users get NullPointerException in fragment class when calls getActivity() method.

活动

pulic class MyActivity extends FragmentActivity{

private ViewPager pager; 
private TitlePageIndicator indicator;
private TabsAdapter adapter;

 @Override
public void onCreate(Bundle savedInstanceState) {

    pager = (ViewPager) findViewById(R.id.pager);;
    indicator = (TitlePageIndicator) findViewById(R.id.indicator);
    adapter = new TabsAdapter(getSupportFragmentManager(), false);

    adapter.addFragment(new FirstFragment());
    adapter.addFragment(new SecondFragment());
    indicator.notifyDataSetChanged();
    adapter.notifyDataSetChanged();

    // push first task
    FirstTask firstTask = new FirstTask(MyActivity.this);
    // set first fragment as listener
    firstTask.setTaskListener((TaskListener) adapter.getItem(0));
    firstTask.execute();

}

 indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            Fragment currentFragment = adapter.getItem(position);
            ((Taskable) currentFragment).executeTask();
        }

        @Override
        public void onPageScrolled(int i, float v, int i1) {}

        @Override
        public void onPageScrollStateChanged(int i) {}
 });

}

的AsyncTask类

AsyncTask class

public class FirstTask extends AsyncTask{

private TaskListener taskListener;

...

@Override
protected void onPostExecute(T result) {
   ...  
   taskListener.onTaskComplete(result);
}

}

片段类

public class FirstFragment extends Fragment immplements Taskable, TaskListener{


public FirstFragment() {
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.first_view, container, false);;
}

@Override
public void executeTask() {
    FirstTask firstTask = new FirstTask(MyActivity.this);
    firstTask.setTaskListener(this);
    firstTask.execute();
}


@Override
public void onTaskComplete(T result) {
    // NPE is here 
    Resources res = getActivity().getResources();
    ...
}

}

也许当应用程序从后台恢复这个错误发生。在这种情况下,我应该如何处理这种情况正常吗?

Maybe this error happens when applications resumed from background. In this case how I should handle this situation properly?

推荐答案

看来我找到了解决我的问题。 很好的说明中给出这里 和的这里。 这是我的例子:

It seems that I found a solution to my problem. Very good explanations are given here and here. Here is my example:

pulic class MyActivity extends FragmentActivity{

private ViewPager pager; 
private TitlePageIndicator indicator;
private TabsAdapter adapter;
private Bundle savedInstanceState;

 @Override
public void onCreate(Bundle savedInstanceState) {

    .... 
    this.savedInstanceState = savedInstanceState;
    pager = (ViewPager) findViewById(R.id.pager);;
    indicator = (TitlePageIndicator) findViewById(R.id.indicator);
    adapter = new TabsAdapter(getSupportFragmentManager(), false);

    if (savedInstanceState == null){    
        adapter.addFragment(new FirstFragment());
        adapter.addFragment(new SecondFragment());
    }else{
        Integer  count  = savedInstanceState.getInt("tabsCount");
        String[] titles = savedInstanceState.getStringArray("titles");
        for (int i = 0; i < count; i++){
            adapter.addFragment(getFragment(i), titles[i]);
        }
    }


    indicator.notifyDataSetChanged();
    adapter.notifyDataSetChanged();

    // push first task
    FirstTask firstTask = new FirstTask(MyActivity.this);
    // set first fragment as listener
    firstTask.setTaskListener((TaskListener) getFragment(0));
    firstTask.execute();

}

private Fragment getFragment(int position){
     return savedInstanceState == null ? adapter.getItem(position) : getSupportFragmentManager().findFragmentByTag(getFragmentTag(position));
}

private String getFragmentTag(int position) {
    return "android:switcher:" + R.id.pager + ":" + position;
}

 @Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("tabsCount",      adapter.getCount());
    outState.putStringArray("titles", adapter.getTitles().toArray(new String[0]));
}

 indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            Fragment currentFragment = adapter.getItem(position);
            ((Taskable) currentFragment).executeTask();
        }

        @Override
        public void onPageScrolled(int i, float v, int i1) {}

        @Override
        public void onPageScrollStateChanged(int i) {}
 });

在此code的主要思想是,在运行应用程序通常,您可以创建新的碎片,并将它们传递到适配器。当您恢复您的应用程序片段的经理已经有此片段的情况下,你需要从片段经理得到它,并把它传递给适配器。

The main idea in this code is that, while running your application normally, you create new fragments and pass them to the adapter. When you are resuming your application fragment manager already has this fragment's instance and you need to get it from fragment manager and pass it to the adapter.

更新

此外,它是利用碎片时检查isAdded getActivity前()被称为一个很好的做法。这有助于避免一个零指示字例外,当片段从该活动分离。例如,一个活动可能包含推动一个异步任务的片段。当任务完成时,onTaskComplete听者称为

Also, it is a good practice when using fragments to check isAdded before getActivity() is called. This helps avoid a null pointer exception when the fragment is detached from the activity. For example, an activity could contain a fragment that pushes an async task. When the task is finished, the onTaskComplete listener is called.

@Override
public void onTaskComplete(List<Feed> result) {

    progress.setVisibility(View.GONE);
    progress.setIndeterminate(false);
    list.setVisibility(View.VISIBLE);

    if (isAdded()) {

        adapter = new FeedAdapter(getActivity(), R.layout.feed_item, result);
        list.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }

}

如果我们打开片段,推一个任务,然后迅速preSS回调用返回到previous活动,当任务完成后,它会尝试访问活动onPostExecute()所述getActivity()方法。如果活动已经脱落,这种检查是不是有:

If we open the fragment, push a task, and then quickly press back to return to a previous activity, when the task is finished, it will try to access the activity in onPostExecute() by calling the getActivity() method. If the activity is already detached and this check is not there:

if (isAdded()) 

然后应用程序崩溃。

then the application crashes.

这篇关于Android系统。片段getActivity()有时会返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆