我有一個動態添加兩個片段的Activity
。一個是隱藏的(無視圖)Fragment
,它具有setRetainInstance(true)
並處理到我的數據庫處理程序的接口。其目的是啓動AsyncTask
以從數據庫中獲取數據,並偵聽數據庫處理程序以將其結果返回。然後它將通過另一個監聽器將數據傳回Activity
。然後Activity
將把數據交給顯示器Fragment
,該顯示器內有ListView
並且將相應地顯示。在輪流設置非視圖片段偵聽器時活動崩潰
活動:NOT片段活動
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);
}
}
我的問題是:旋轉屏幕時,我的代碼崩潰與上SetListener的Search_Hander在一個空指針異常活動。如果我將Activity
更改爲FragmentActivity
並使用SupportFragmentManager
....這些都不是問題...只需進行這些快速更改即可正常工作(有關現在不推薦使用的onRetainNonConfigurationInstance()
被SupportFragmentManager
覆蓋,它處理所有內容爲你)。
在試圖解決這一問題,我一直是作爲一個Activity
,但放在SearchHolder = (Workout_Search_Holder_Fragment) getFragmentManager.findFragmentByTag("search_holder")
爲else
的一部分,如果R.id.Content
不是null
又給Fragment
一個標籤,當我最初設置它,如果R.id.Content
WAS null
。請參閱上面的註釋代碼。這工作,但創造了另一個問題,onActivityCreated
再次啓動,並啓動我的AsyncTask時,我不想要它。我無法發送或檢查savedInstanceState
數據包中的變量,因爲setRetainInstance(true)
是空的。我知道我做錯了什麼,但無法繞過它。
我最初試過所有這些....它的工作,但現在片段調用onActivityCreated時,我抓住了Else部分的舊片段。我應該從OnCreate做我的AsyncTask,所以它不會被調用兩次(因爲OnCreate不會再次調用,如果我保留片段,但OnActivityCreated)。我唯一擔心的是,在我的偵聽器被設置爲活動之前,任務可能會完成。有趣的是,如果我使用FragmenyActivity和SupportFragmentManager ...,爲什麼行爲不同呢? – 2014-10-04 03:10:30
你想讓異步任務只執行一次嗎?爲什麼不能在提交事務之前設置監聽器,以便在從分段的oncreate執行異步任務時監聽器將可用?我想知道你說「使用FragmentActivity與SupportFragmentManager時需要NONE」,我還沒有遇到過這種行爲。 – Dinash 2014-10-04 03:50:36
無論屏幕旋轉多少次,只需進行一次活動創建即可。持有者片段用於允許活動在旋轉的情況下保留正在運行的後臺代碼。持有者片段的唯一責任是在我的DataHelper(另一個從opensqlhelper擴展的獨立類)中啓動sql查詢,並將它接收到的結果傳遞給活動。然後該活動將這些結果傳遞給顯示片段以進行顯示。 – 2014-10-04 03:55:38