[英]Where to fire the asynctask in a fragment activity
我有一個片段活動,想從我的PHP腳本中獲取數據。 我需要這些數據來有效地繪制用戶界面。 我的問題是在我取回數據之前我的UI /片段已繪制完畢,我不確定為什么要盡早在onCreate中將其觸發。 我在前后放置了一個對話框來有效凍結UI,而在后台檢索數據,但是....我看不到這種情況,我認為調用它太晚了,因為在調試過程中對話框出現時它顯示在繪制的屏幕上方這讓我感到困惑。
我有一個替代解決方案,該方法是在調用活動(先前的活動)中觸發asyncTask並將結果傳遞到捆綁包中,但我不喜歡這種解決方案,因為它過於嚴格,可能會導致屏幕旋轉問題。
我已經堅持了很長時間,任何人都可以告訴我將異步執行放在哪里-對話框應該有效地使其成為同步過程。 我將asynctask放置在我認為可能/明智且沒有運氣的任何地方。
在下面,我在oncreate()
執行。 請注意,execute不會做任何事情,只是更新一個測試字符串,該字符串事先是“ no change”,在后執行中是“ changed”,因此我可以在代碼的各個點看到它的狀態。 在我繪制屏幕之前,它不會改變。
public class StaggeredGridActivityFragment extends FragmentActivity {
String test ="not changed";
private TilesAdapter mAdapter;
private ArrayList<String> mData;
private StaggeredGridView mGridView;
private static final String TAG = "StaggeredGridActivityFragment";
@Override
protected void onCreate(Bundle savedInstanceState) {
try
{
// Loading tile data in Background Thread
new GetLoginTiles().execute();
}
catch (Exception e)
{
e.printStackTrace();
}
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar
final FragmentManager fm = getSupportFragmentManager();
// Create the list fragment and add it as our sole content.
if (fm.findFragmentById(android.R.id.content) == null) {
final StaggeredGridFragment fragment = new StaggeredGridFragment();
fm.beginTransaction().add(android.R.id.content, fragment).commit();
}
Intent i=getIntent();
Bundle extras = i.getExtras();
String tmp = extras.getString("myKey");
}
private class StaggeredGridFragment extends Fragment implements AbsListView.OnScrollListener, AbsListView.OnItemClickListener {
//private StaggeredGridView mGridView;
private boolean mHasRequestedMore;
// private TilesAdapter mAdapter;
//private ArrayList<String> mData;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_sgv, container, false);
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Encapsulate all within a post cereate from a async task or call a blocking http call
super.onActivityCreated(savedInstanceState);
mGridView = (StaggeredGridView) getView().findViewById(R.id.grid_view);
if (savedInstanceState == null) {
final LayoutInflater layoutInflater = getActivity().getLayoutInflater();
View header = layoutInflater.inflate(R.layout.list_item_header_footer, null);
mGridView.addHeaderView(header);
}
if (mAdapter == null) {
mAdapter = new TilesAdapter(getActivity(), R.id.summary1_value);
}
if (mData == null) {
mData = ActivityTileData.getLoginTileDataArray(getActivity());
}
for (String data : mData) {
mAdapter.add(data); //Add each mData TileAdapter element to an mAdapter where it will be further broken down and used by the TileAdapter
}
mGridView.setAdapter(mAdapter);
mGridView.setOnScrollListener(this);
mGridView.setOnItemClickListener(this);
}
@SuppressLint("LongLogTag")
@Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
Log.d(TAG, "onScrollStateChanged:" + scrollState);
}
@SuppressLint("LongLogTag")
@Override
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) {
Log.d(TAG, "onScroll firstVisibleItem:" + firstVisibleItem +
" visibleItemCount:" + visibleItemCount +
" totalItemCount:" + totalItemCount);
// our handling
if (!mHasRequestedMore) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if (lastInScreen >= totalItemCount) {
Log.d(TAG, "onScroll lastInScreen - so load more");
mHasRequestedMore = true;
onLoadMoreItems();
}
}
}
//Loads all of the objects from the getLoginTileData() if called
private void onLoadMoreItems() {
while(mAdapter.getCount()<mData.size()) {
//final ArrayList<String> sampleData = SampleData.generateSampleData();
final ArrayList<String> loginTileData = ActivityTileData.getLoginTileDataArray(getActivity());
for (String data : loginTileData) {
mAdapter.add(data.toString());
}
// stash all the data in our backing store
mData.addAll(loginTileData);
// notify the adapter that we can update now
mAdapter.notifyDataSetChanged();
mHasRequestedMore = false;
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Toast.makeText(getActivity(), "Item Clicked: " + position, Toast.LENGTH_SHORT).show();
}
}
// Progress Dialog
private ProgressDialog qDialog;
// JSON parser class
JSONParser jParser = new JSONParser();
String url_login ="http://xxx/xxx.php";
/**
* Background Async Task to Load all images by making HTTP Request
* */
class GetLoginTiles extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
qDialog = new ProgressDialog(StaggeredGridActivityFragment.this);
qDialog.setMessage("Please wait...");
qDialog.setIndeterminate(false);
qDialog.setCancelable(false);
qDialog.show();
}
@Override
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject jsonLogin = jParser.makeHttpRequest(url_login, "GET", params);
test=jsonLogin.toString();
return jsonLogin.toString();
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String jsonString) {
// dismiss the dialog after getting all questions
qDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into imagebuttons
* */
test="local test has changed";
}
});
}
}
}
我有一個替代解決方案,該方法是在調用活動(先前的活動)中觸發asyncTask並將結果傳遞到捆綁包中,但我不喜歡這種解決方案,因為它過於嚴格,可能會導致屏幕旋轉問題。
這是一個很好的方法
覆蓋onSaveInstanceState以保存旋轉之間的附加功能
也可以在這里查看更多詳細信息
編輯:似乎您正在嘗試使用更改文本
test =“本地測試已更改”;
你需要做的是將活動傳遞給asynctask然后
VIEWTYPEHERE button= ( VIEWTYPEHERE) activity.findViewById(R.id.YOUR_VIEW"S_ID_HERE);
button.setText(“”);
幾個注意事項
在ui線程上執行后執行時,您不需要新的可運行對象,也忘記在其上調用.run()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.