我有Activity
动态添加两个片段。一个是具有Fragment
的隐藏(无视图)setRetainInstance(true)
并处理我的数据库处理程序的接口。其目的是启动AsyncTask
以从数据库中获取数据并监听数据库处理程序以返回其结果。然后它会通过另一个侦听器将数据传回Activity
。然后,Activity
会将数据传递到显示Fragment
的显示ListView
,并会相应显示。
活动:不是碎片活动
import android.app.Activity;
import android.os.Bundle;
public class Workout_Search_Display_Activity extends Activity {
private final String search_string = "SEARCH_STRING";
private final String search_type = "SEARCH_TYPE";
private String Search_String = "";
private String Search_Type = "";
private Workout_Search_Holder_Fragment SearchHolder;
private Workout_Search_Display_Fragment search_display_fragment;
private Workout_Search_Activity_Listener WSAL;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Search_String = getIntent().getStringExtra(search_string);
Search_Type = getIntent().getStringExtra(search_type);
if (getFragmentManager().findFragmentById(android.R.id.content) == null) {
SearchHolder = Workout_Search_Holder_Fragment.newInstance(Search_String, Search_Type);
getFragmentManager().beginTransaction()
.add(android.R.id.content, SearchHolder).commit();
search_display_fragment = Workout_Search_Display_Fragment.newInstance();
getFragmentManager().beginTransaction()
.add(android.R.id.content, search_display_fragment).commit;
} //added too try to fix// else
//added to try to fix// SearchHolder = (Workout_Search_Holder_Fragment) getFragmentManager.findFragmentByTag("search_holder");
WSAL = new Workout_Search_Activity_Listener() {
public void NothingFound() {
search_display_fragment.no_data();
}
public void results_found(ArrayList<Search_Results_Holder> results) {
search_display_fragment.is_data();
search_display_fragment.handover_data(results);
}
};
SearchHolder.setListener(WSAL);
}
}
片段:
import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
public class Workout_Search_Holder_Fragment extends Fragment implements DatabaseHelper.Workout_Search_Listener {
private String Search_String = "";
private String Search_Type = "";
private final static String search_string = "SEARCH_STRING";
private final static String search_type = "SEARCH_TYPE";
private Workout_Search_Activity_Listener listener;
protected static Workout_Search_Holder_Fragment newInstance(
String Search_String, String Search_Type) {
Workout_Search_Holder_Fragment f = new Workout_Search_Holder_Fragment();
Bundle args = new Bundle();
args.putString(search_string, Search_String);
args.putString(search_type, Search_Type);
f.setArguments(args);
return f;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
Search_String = getArguments().getString(search_string, null);
Search_Type = getArguments().getString(search_type, null);
sendSearch();
}
public Workout_Search_Activity_Listener getListener() {
return listener;
}
public void setListener(Workout_Search_Activity_Listener listener) {
this.listener = listener;
}
private void sendSearch() {
DatabaseHelper.getInstance(getActivity()).getSearchResultsAsync(
Search_String, Search_Type, this);
}
static public <T> void executeAsyncTask(AsyncTask<T, ?, ?> task, T... params) {
if (Build.VERSION.SDK_INT > +Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
} else {
task.execute(params);
}
}
@Override
public void return_no_results_found() {
listener.NothingFound();
}
@Override
public void return_search_results(ArrayList<Search_Results_Holder> results) {
Log.v("workout search holder fragment", "results found in fragment, handing off to activity");
listener.results_found(results);
}
}
我的问题是:当旋转屏幕时,我的代码在活动中的Search_Hander的SetListener上以Null Pointer Exception崩溃。如果我将Activity
更改为FragmentActivity
并使用SupportFragmentManager
....这一切都不是问题...只有那些快速更改才能正常工作(有关现在的事情) -preprecated onRetainNonConfigurationInstance()
被SupportFragmentManager
覆盖,它会为您处理所有事情。
在尝试解决此问题时,我将其保留为Activity
,但如果SearchHolder = (Workout_Search_Holder_Fragment) getFragmentManager.findFragmentByTag("search_holder")
不是{{1},则将else
作为R.id.Content
的一部分放入如果null
WAS Fragment
,我最初设置时会给R.id.Content
一个标记。请参阅上面注释掉的代码。这有效,但创建了另一个问题,null
再次启动,并在我不想要的时候启动了我的AsyncTask。我无法将onActivityCreated
包中的变量发送或检查到片段,因为savedInstanceState
为空。我知道我做错了什么,但无法绕过它。
答案 0 :(得分:1)
您正在使用
添加(ANDROID.R.id.content,SearchHolder)
添加片段时,请尝试
添加(ContainerID,SearchHolder,&#34; search_holder&#34;),确保您的片段添加了标记&#34; search_holder&#34;
然后就像你在其他部分那样尝试通过调用
获取该片段对象findFragmentByTag() 方法
希望这有帮助!!!
答案 1 :(得分:0)
答案有两个:
Fragments
,我知道。AsyncTask
。我不知道。事实证明,我的AsyncTask
重新执行,因为OnActivityCreated
再次被调用,即使设置了saveInstanceState(true)
也是如此。但是,onCreate
不是。通过将调用方法更改为onCreate
,我确保AsyncTask
仅被调用一次,因为它不会在Activity
重新创建时再次调用。在Activity中,我仍然需要在测试时重置我的两个片段的持有者,如果R.id.content
是非null,抓住那些与标签匹配的片段......这是Dinash给出的答案的一部分。
if (getFragmentManager().findFragmentById(android.R.id.content) == null) {
SearchHolder = Workout_Search_Holder_Fragment.newInstance(
Search_String, Search_Type, false);
getFragmentManager().beginTransaction()
.add(android.R.id.content, SearchHolder, "searchholder")
.commit();
search_display_fragment = Workout_Search_Display_Fragment
.newInstance();
getFragmentManager()
.beginTransaction()
.add(android.R.id.content, search_display_fragment,
"displayholder").commit();
} else {
Log.v("activity", "non-null holder");
SearchHolder = (Workout_Search_Holder_Fragment) getFragmentManager()
.findFragmentByTag("searchholder");
search_display_fragment = (Workout_Search_Display_Fragment) getFragmentManager()
.findFragmentByTag("displayholder");
}
除了自己重新附加FragmentManager
之外, Fragments
要求我测试内容为空,这是FragmentSupportManager
不需要的内容。这也要求我保存我正在为ListView
再次使用的ArrayList ... FragmentSupportManager
自己完成所有这些操作而不会刺激我。
我仍然很好奇为什么FragmentActivity
的这种行为有所不同,因为它似乎为我照顾所有这些并且需要最少的努力/代码才能工作。