在屏幕方向上,使用Async Task再次加载数据

时间:2014-05-27 21:20:59

标签: android android-fragments android-orientation

我使用主/详细模式制作Android应用程序。所以我有

  • ListActivity类,它是FragmentActivity和
  • ListFragment类是Fragment

这一切都很完美,但是当我更改屏幕方向时,它会再次调用AsyncTask并重新加载所有数据。

以下是我处理所有逻辑的 ListActivity 类的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list);

    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);
    getActionBar().setTitle("Dnevni horoskop");


    if(findViewById(R.id.details_container) != null){
        //Tablet
        mTwoPane = true;

        //Fragment stuff
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        DetailsFragment df = new DetailsFragment();
        ft.add(R.id.details_container, df);
        ft.commit();
    }

    pb = (ProgressBar) findViewById(R.id.pb_list);
    tvNoConnection = (TextView) findViewById(R.id.tv_no_internet);
    ivNoConnection = (ImageView) findViewById(R.id.iv_no_connection);
    list = (GridView) findViewById(R.id.gv_list);

    if(mTwoPane == true){
        list.setNumColumns(1);
        //list.setPadding(16,16,16,16);
    }

    adapter = new CustomListAdapter();      

    list.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                long arg3) {
            pos = position;
            if(mTwoPane == false){
                Bundle bundle = new Bundle();
                bundle.putSerializable("zodiac", zodiacFeed);
                Intent i = new Intent(getApplicationContext(), DetailsActivity.class);
                i.putExtra("position", position);
                i.putExtras(bundle);
                startActivity(i);
                overridePendingTransition(R.anim.right_in, R.anim.right_out);
            }
            else if(mTwoPane == true){
                DetailsFragment fragment = (DetailsFragment) getSupportFragmentManager().findFragmentById(R.id.details_container);
                fragment.setHoroscopeText(zodiacFeed.getItem(position).getText());
                fragment.setLargeImage(zodiacFeed.getItem(position).getLargeImage());
                fragment.setSign("Dnevni horoskop - "+zodiacFeed.getItem(position).getName());
                fragment.setSignDuration(zodiacFeed.getItem(position).getDuration());
                 // inflate menu from xml
                /*if(menu != null){
                 MenuItem item = menu.findItem(R.id.share);
                 Toast.makeText(getApplicationContext(), item.getTitle().toString(), Toast.LENGTH_SHORT).show();
                }*/
            }

        }
    });

    if(!Utils.isConnected(getApplicationContext())){
        pb.setVisibility(View.GONE);
        tvNoConnection.setVisibility(View.VISIBLE);
        ivNoConnection.setVisibility(View.VISIBLE);
    }

   //Calling AsyncTask to load data
        Log.d("TAG", "loading");
        HoroscopeAsyncTask task = new HoroscopeAsyncTask(pb);
        task.execute();



}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
}

class CustomListAdapter extends BaseAdapter {

    private LayoutInflater layoutInflater;

    public CustomListAdapter() {

        layoutInflater = (LayoutInflater) getBaseContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

    }

    public int getCount() {
        // TODO Auto-generated method stub
        // Set the total list item count
        return names.length;
    }

    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // Inflate the item layout and set the views
        View listItem = convertView;
        int pos = position;     

        zodiacItem = zodiacList.get(pos);

        if (listItem == null && mTwoPane == false) {
            listItem = layoutInflater.inflate(R.layout.list_item, null);
        }
        else if(mTwoPane  == true){
            listItem = layoutInflater.inflate(R.layout.tablet_list_item, null);

        }

        // Initialize the views in the layout
        ImageView iv = (ImageView) listItem.findViewById(R.id.iv_horoscope);
        iv.setScaleType(ScaleType.CENTER_CROP);
        TextView tvName = (TextView) listItem.findViewById(R.id.tv_zodiac_name);
        TextView tvDuration = (TextView) listItem.findViewById(R.id.tv_duration);


        iv.setImageResource(zodiacItem.getImage());
        tvName.setText(zodiacItem.getName());
        tvDuration.setText(zodiacItem.getDuration());   

        Animation animation =  AnimationUtils.loadAnimation(getBaseContext(), R.anim.push_up);

        listItem.startAnimation(animation);
        animation = null;
        return listItem;
    }

}

  private void getHoroscope() {     

    String urlString = "http://balkanandroid.com/download/horoskop/examples/dnevnihoroskop.php";
    try {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(urlString);

        HttpResponse response = client.execute(post);
        resEntity = response.getEntity();
        response_str = EntityUtils.toString(resEntity);
        if (resEntity != null) {
            Log.i("RESPONSE", response_str);
            runOnUiThread(new Runnable() {
                public void run() {
                    try {                       

                        Log.d("TAG", "Response from server : n "
                                + response_str);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    } catch (Exception ex) {
        Log.e("TAG", "error: " + ex.getMessage(), ex);
    }
}

private class HoroscopeAsyncTask extends AsyncTask<String, Void, Void> {


    public HoroscopeAsyncTask(ProgressBar pb1){
        pb = pb1;
    }

    @Override
    protected void onPreExecute() {
        pb.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(String... params) {

        getHoroscope();

        try {
            Log.d("TAG", "test u try");

            JSONObject jsonObject = new JSONObject(response_str);
            JSONArray jsonArray = jsonObject.getJSONArray("horoscope");
            for(int i=0;i<jsonArray.length();i++){
                Log.d("TAG", "test u for");

                JSONObject horoscopeObj = jsonArray.getJSONObject(i);
                String horoscopeSign = horoscopeObj.getString("name_sign");
                String horoscopeText = horoscopeObj.getString("txt_hrs");

                zodiacItem = new ZodiacItem(horoscopeSign, horoscopeText, duration[i], images[i], largeImages[i]);
                zodiacList.add(zodiacItem);
                zodiacFeed.addItem(zodiacItem);

                //Treba u POJO klasu ubaciti sve.
                Log.d("TAG", "ZNAK: "+zodiacItem.getName()+" HOROSKOP: "+zodiacItem.getText());

            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Log.e("TAG", "error: " + e.getMessage(), e);

        }       

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        pb.setVisibility(View.GONE);
        list.setAdapter(adapter);
        adapter.notifyDataSetChanged();
        super.onPostExecute(result);
    }


}

以下是 ListFragment 类的代码:

public class ListFragment extends Fragment {


@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub

     // Retain this fragment across configuration changes.
    setRetainInstance(true);
    super.onCreate(savedInstanceState);


}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View view = inflater.inflate(R.layout.fragment_list, container, false); 

    return view;
}

}

3 个答案:

答案 0 :(得分:0)

我认为部分问题可能是方向改变再次调用onCreate。

See this question,然后检查第二个答案。

只需将configChanges添加到android清单就不会解决问题,但是如果你覆盖onConfigurationChanged,你可以设置一个SharedPreferences值,你说&#34; AsynTaskStarted = true&#34;或类似的东西,所以当方向改变时,你可以检查这个标志,如果不存在则启动AsyncTask,如果它已经在运行,则跳过它。

This other question,由链接的第一个问题的第一个答案引用,似乎有更多信息。

答案 1 :(得分:0)

当方向更改时,您可以使用以下内容保留任务:

@Override
public HoroscopeAsyncTask onRetainCustomNonConfigurationInstance() {
    return task;
}

然后在你的onCreate()中你可以这样做:

task = (HoroscopeAsyncTask)this.getLastCustomNonConfigurationInstance();
if(task != null) {
    //pass the new progressbar reference to the asynctask
    //implement a method in the asynctask that returns the task result 
    //e.g. result = task.getResult();
    // if the result is not null, it means the task finished its work while orientation
    // changed, if the result is null, onPostExecute will take care of that.
    //if(result != null) { //set the result in the listview }
} else {
    HoroscopeAsyncTask task = new HoroscopeAsyncTask(pb);
    task.execute();
}

如果没有(应用程序启动)执行新的asynctask,如果有一个(方向更改)使用现有的运行asynctask,则代码试图获取保留的tak。

答案 2 :(得分:-1)

在清单m8 android:configChanges="orientation|keyboardHidden"

中尝试此代码