Android AsyncTask: не работает пользовательский интерфейс в Android из фоновой задачи - PullRequest
0 голосов
/ 30 августа 2018

Что я хочу:

  • ждать соединения. Пока соединение не получено, отобразите пустой экран
  • как только подключите, установите текущий вид на пользовательский вид (используя setContentView()). Это я пытаюсь сделать из Background Thread (AsyncTask)
  • Затем, после этого, я продолжу принимать баллы от клиента и буду обновлять их в потоке пользовательского интерфейса. Для этого я принимаю баллы от клиента и отправляю на publishProgess()

Но по какой-то причине сам второй шаг не работает.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    public  ServerSocket server;
    public  Socket       socket;
    public  Slate        slate ;
    private Paint        mPaint;
    public static MainActivity context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        (new ServerTask()).execute();
    }



    public static MainActivity getContext()
    {
        return context;
    }

    public void start_slate(){
        slate = new Slate(this);
        slate.setBackgroundColor(Color.parseColor("#000000"));
        setContentView(slate);
    }

    public class Slate extends View {
    .....
    .....
       draw(){
       ....
       ....
       }
    } /*custom drawing view*/
}

Фоновое задание

/*Background Task*/
class ServerTask extends AsyncTask<Void, Action, Void>
{

    private WeakReference<MainActivity> mainActivity;
    private Action action;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mainActivity = new WeakReference<>(MainActivity.getContext());
    }

    @Override
    protected Void doInBackground(Void... voids) {
        ObjectInputStream stream;

        try{
            mainActivity.get().server = new ServerSocket(3107);
            mainActivity.get().socket = mainActivity.get().server.accept();
            stream = new ObjectInputStream(mainActivity.get().socket.getInputStream());

            MainActivity.getContext().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    MainActivity.getContext().start_slate();
                }
            }); /*BUT THE VIEW IS NOT CHANGING*/

            while(true)
            {
                if(isCancelled()){
                    break;
                }
                action = (Action)stream.readObject();
                publishProgress(action);
            }
        }catch (Exception exception)
        {
            exception.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Action... actions) {
        super.onProgressUpdate(actions);
        ((mainActivity.get()).slate).draw(actions[0]);
    }/*this will send the co-ordinates to current drawing view*/

}

ПРИМЕЧАНИЕ: даже если я попытаюсь установить вид в onProgressUpdate(), этого все равно не произойдет. Это происходит только в onPostExecute(). Но я не хочу этого, потому что после изменения вида мне все равно приходится принимать координаты (часть цикла while)

...