Как разрешить ротацию устройства во время работы 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 по своей природе является блокировкой пользовательского интерфейса, что делает его отчасти невозможным. Я оставлю вопрос на случай, если у кого-то возникнут другие мысли!

0 ответов

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