在片段活动中触发asynctask的位置

时间:2015-03-31 10:46:37

标签: android http android-fragments android-asynctask dialog

我有一个片段活动,想从我的PHP脚本中获取数据。我需要这些数据来有效地绘制我的ui。我的问题是我的UI /片段在我获取数据之前绘制,我不知道为什么我尽可能早地在onCreate'中解雇它。我在前后发布了一个对话框来有效地冻结UI,同时在后台检索数据但是......我没有看到这种情况发生,我认为在调试过程中出现对话框时调用它时为时已晚,它显示在绘制屏幕的顶部这让我感到困惑。

我有一个替代解决方案,即在调用活动(上一个活动)中触发asyncTask并将结果传递给bundle但我不喜欢这个解决方案,因为它很僵硬,可能会导致屏幕旋转问题。

我已经坚持了很多年,任何人都可以告诉我具体执行异步执行的位置 - 对话框应该有效地使其成为同步过程。我把我的asynctask放在任何地方,我认为可能/明智,没有运气。

在下面我有oncreate()中的执行。请注意,执行并不是任何事情,只是事先更新一个“无变化”的测试字符串,并在postexecute中“更改”,这样我就能看到它在代码中各个点的状态。在我绘制屏幕之前它没有改变。

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

        }
    }
}

1 个答案:

答案 0 :(得分:0)

  

我有一个替代解决方案,即在调用活动(上一个活动)中触发asyncTask并将结果传递给bundle但我不喜欢这个解决方案,因为它很僵硬,可能会导致屏幕旋转问题。

这是一个很好的方法

覆盖onSaveInstanceState以在旋转之间保存额外内容

另请参阅here了解详情

编辑:您似乎正在尝试使用

更改文字

test =&#34;本地测试已更改&#34 ;;

你需要做的是将活动传递给asynctask然后

VIEWTYPEHERE button= ( VIEWTYPEHERE)  activity.findViewById(R.id.YOUR_VIEW"S_ID_HERE);

button.setText(&#34;&#34);

几个笔记

关于post执行在ui线程上运行你不需要新的runnable 你忘了给它打电话.run()