2015-05-27 1 views
2

Этот код не работает при повороте экрана. Я пытаюсь использовать обработчик, но сообщения отправляются в предыдущую активность (до поворота) и на новую активность.Обновление пользовательского интерфейса от AsyncTask и правильная обработка экрана. Вращение

¿Как поток может отправлять сообщения в новую активность? Пожалуйста, не рекомендуется избегать поворота экрана.

public class SampleActivity extends Activity { 
    TextView text; 
    Handler handler; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     LinearLayout layout = new LinearLayout(this); 
     layout.setOrientation(LinearLayout.VERTICAL); 
     text = new TextView(this); 
     text.setText("HELLO"); 

     layout.addView(text); 
     if (savedInstanceState != null) { 
      text.setText(savedInstanceState.getString("text")); 
     } 

     setContentView(layout); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putString("text", text.getText().toString()); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     new CounterTask().execute(); 
    } 

    public class CounterTask extends AsyncTask<Void, String, Void> { 

     @Override 
     protected Void doInBackground(Void... params) { 
      for (int i = 0; i < 100; i++) { 
       try { 
        Thread.sleep(100); 
        publishProgress("Hello " + i); 
       } catch (Exception e) { 

       } 
      } 
      return null; 
     } 

     @Override 
     protected void onProgressUpdate(String... values) { 
      String str = values[0]; 
      text.setText(str); 
     } 
    } 
} 

ответ

2

Вы можете запустить AsyncTask в нераспределенной фрагменте.

public class TaskFragment extends Fragment { 
    private Callback mCallback; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setRetainInstance(true); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 

     try { 
      mCallback = (Callback) activity; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() 
        + " must implement TaskFragment.Callback"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 

     mCallback = null; 
    } 

    public void execute(){ 
     new CounterTask().execute(); 
    } 

    public interface Callback { 
     void onTaskUpdate(String value); 
    } 

    public class CounterTask extends AsyncTask<Void, String, Void> { 
     @Override 
     protected Void doInBackground(Void... params) { 
      for (int i = 0; i < 100; i++) { 
       try { 
        Thread.sleep(100); 
        publishProgress("Hello " + i); 
       } catch (Exception e) { 

       } 
      } 
      return null; 
     } 

     @Override 
     protected void onProgressUpdate(String... values) { 
      if(mCallback != null) { 
       String str = values[0]; 
       mCallback.onTaskUpdate(str); 
      } 
     } 
    } 
} 

Затем выполните обратный вызов в своей деятельности и добавьте фрагмент через диспетчер фрагментов.

public class SampleActivity extends Activity implements 
     TaskFragment.Callback { 
    private static final String TAG_TASK_FRAGMENT = "task_fragment"; 

    private TaskFragment mTaskFragment; 

    private TextView text; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     LinearLayout layout = new LinearLayout(this); 
     layout.setOrientation(LinearLayout.VERTICAL); 
     text = new TextView(this); 
     text.setText("HELLO"); 

     layout.addView(text); 
     if (savedInstanceState != null) { 
      text.setText(savedInstanceState.getString("text")); 
     } 

     setContentView(layout); 

     FragmentManager fm = getFragmentManager(); 
     mTaskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT); 

     if(mTaskFragment == null){ 
      mTaskFragment = new TaskFragment(); 
      fm.beginTransaction() 
        .add(mTaskFragment, TAG_TASK_FRAGMENT) 
        .commit(); 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putString("text", text.getText().toString()); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     mTaskFragment.execute(); 
    } 

    @Override 
    public void onTaskUpdate(String value) { 
     text.setText(value); 
    } 
} 
0

Вы можете использовать AsyncTaskLoader. Он будет обрабатывать все операции поворота и жизненного цикла вашей активности/фрагмента.

0

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

Добавить протекающую строку наклейки активности в AndroidManifest.xml

android:configChanges="orientation|keyboardHidden|screenSize" 

и этот метод вам SampleActivity.java

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    // when screen rotated, this method will be called instead of onCreate 
}