На экране ориентация снова загружает данные с помощью Async Task

Я делаю приложение для Android с шаблоном master/detail. Так что я

  • Класс ListActivity, который является FragmentActivity и
  • Класс ListFragment, который является Фрагментом

Все работает отлично, но когда я меняю ориентацию экрана, он снова вызывает 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 ответа

При изменении ориентации вы можете использовать следующее для сохранения задачи:

@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();
}

код пытается получить сохраненные такты, если не один (приложение запущено), выполняет новую асинктическую задачу, если существует одна (изменение ориентации), используйте существующую запущенную асинктическую задачу.

Я полагаю, что частью проблемы может быть то, что изменение ориентации снова вызывает функцию Create.

Посмотрите этот вопрос и проверьте второй ответ.

Простое добавление configChanges в манифест Android не решит проблему, но если вы переопределите onConfigurationChanged, вы можете, например, установить значение SharedPreferences, если вы говорите "AsynTaskStarted=true" или что-то в этом роде, поэтому при изменении ориентации вы можете проверить этот флаг и либо запустите AsyncTask, если его нет, просто пропустите его, если он уже запущен.

Этот другой вопрос, на который ссылается первый ответ на первый связанный вопрос, кажется, имеет больше информации.

Попробуй этот код в манифесте m8 android:configChanges="orientation|keyboardHidden"

Другие вопросы по тегам