gpt4 book ai didi

安卓。 fragment getActivity() 有时返回 null

转载 作者:IT老高 更新时间:2023-10-28 12:53:37 25 4
gpt4 key购买 nike

在开发者控制台错误报告中,有时我会看到带有 NPE 问题的报告。我不明白我的代码有什么问题。在模拟器上,我的设备应用程序在没有强制关闭的情况下运行良好,但是当调用 getActivity() 方法时,一些用户在 fragment 类中得到 NullPointerException。

Activity

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 类

public class FirstTask extends AsyncTask{

private TaskListener taskListener;

...

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

fragment 类

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

当应用程序从后台恢复时,可能会发生此错误。在这种情况下我应该如何正确处理这种情况?

最佳答案

看来我找到了解决问题的方法。给出了很好的解释herehere .这是我的例子:

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) {}
});

这段代码的主要思想是,在正常运行应用程序时,您会创建新 fragment 并将它们传递给适配器。当您恢复应用程序 fragment 管理器时,您已经拥有该 fragment 的实例,您需要从 fragment 管理器获取它并将其传递给适配器。

更新

此外,在调用 getActivity() 之前使用 fragment 检查 isAdded 是一个好习惯。当 fragment 与 Activity 分离时,这有助于避免空指针异常。例如,一个 Activity 可能包含一个推送异步任务的 fragment 。任务完成后,会调用 onTaskComplete 监听器。

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

}

如果我们打开fragment,push一个task,然后快速按回返回上一个activity,当task完成后,它会通过调用getActivity()方法尝试访问onPostExecute()中的activity。如果 Activity 已分离且此检查不存在:

if (isAdded()) 

然后应用程序崩溃。

关于安卓。 fragment getActivity() 有时返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11631408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com