Как разрешить ротацию устройства во время работы onPostExecute (задача блокировки пользовательского интерфейса)
Я новичок в Android, но на основании моего понимания, что onPostExecute должен запускаться в основном потоке пользовательского интерфейса, чтобы иметь возможность доступа к представлениям и т. Д., Который блокирует пользовательский интерфейс до его завершения. Но приложение выглядит некрасиво - как будто оно выходит из строя - когда я пытаюсь повернуть устройство во время работы onPostExecute (я знаю, что это должна быть легкая задача, но я имею в виду медленные телефоны, так что это может действительно произойти в моем HBO)
Теперь, вот мой код, и я знаю, что считаю, что должен использовать интерфейсы для связи между моей Задачей, Фрагментом и Деятельностью, но пока это просто подтверждение концепции.
//MovieTask Class
public class MovieTask extends AsyncTask<Void, Void, String> {
private Activity activity;
public MovieTask(Activity activity) {
onAttach(activity);
}
//should be an interface
public void onAttach(Activity activit) {
this.activity = activit;
}
//should be an interface
public void onDetach() {
this.activity = null;
}
@Override
protected String doInBackground(Void... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
Log.e("ASYNC TASK", "DONE");
return "DONE: FROM DO TO POST";
}
@Override
protected void onPostExecute(String s) {
if(this.activity != null)
{
((MainActivity) activity).ShowResult(s);
Log.e("MovieTask", "Result Received");
}else
Log.e("MovieTask", "Activity is null (1)");
}
}
//My Non-UI Fragment to decouple the Task from the Activity
public class NonUIFragment extends Fragment {
private MovieTask myTask;
private Activity activity;
public NonUIFragment() {
// Required empty public constructor
}
public void BeginTask() {
if (activity != null) {
myTask = new MovieTask(activity);
myTask.execute();
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
//check that the passed context is an Activity first then,
if (context instanceof Activity) {
this.activity = (Activity) context;
if(myTask != null) {
myTask.onAttach((Activity) context);
}
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance
setRetainInstance(true);
}
@Override
public void onDetach() {
super.onDetach();
if(myTask != null) {
myTask.onDetach();
}
}
//Main Activity (Task Consumer)
public class MainActivity extends AppCompatActivity {
NonUIFragment nonUIFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
nonUIFragment = new NonUIFragment();
getSupportFragmentManager()
.beginTransaction()
.add(nonUIFragment, "nonUIFragment")
.commit();
}
else
{
nonUIFragment = (NonUIFragment) getSupportFragmentManager().findFragmentByTag("nonUIFragment");
}
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nonUIFragment.BeginTask();
}
});
}
//should be the consumer interface
public void ShowResult(String result)
{
try {
Thread.sleep(5000);
TextView txtVw = (TextView) findViewById(R.id.txtVw);
txtVw.setText(result);
} catch (InterruptedException e) {
Log.e("MovieTask", "mCallbacks is null (2)");
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
TextView txtVw = (TextView) findViewById(R.id.txtVw);
String result = txtVw.getText().toString();
outState.putString("result", result);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String result = savedInstanceState.getString("result");
TextView txtVw = (TextView) findViewById(R.id.txtVw);
txtVw.setText(result);
}
}
ОБНОВЛЕНИЕ 1
В чате Джигс предложил попробовать 'runOnUiThread', однако onPostExecute уже работает в потоке пользовательского интерфейса, так что, к сожалению, это не имеет значения. Я думаю, что я пытаюсь сделать, это не блокировать пользовательский интерфейс, в то время как поведение onPostExecute по своей природе является блокировкой пользовательского интерфейса, что делает его отчасти невозможным. Я оставлю вопрос на случай, если у кого-то возникнут другие мысли!