Necessary conditions for toast

question:

1. The child thread can modify the UI

2. Necessary conditions for Toast

Solved from source code:

1. At the beginning, the child thread can update the UI, but after a while, the UI cannot be updated
. Send a message in onCreate
EventBus.getDefault().post(new Message("test ", 22));
You can update the UI in the child thread (and No exception will be thrown)
The reason is that the ViewRootImpl class has not been created at this time, and the checkThread() method cannot be called to detect whether it is a UI thread, so you can update the UI
and send a message after clicking the button
@Subscribe(threadMode = ThreadMode.ASYNC )
public void messages(final Message message){}
gets the object and updates the UI in the child thread. At this time, the ViewRootImpl object has been created. Call checkThread() to judge
which thread to execute textView.setText(message.toString()) in. When it is detected that it is not the main thread, the exception CalledFromWrongThreadException is thrown directly. 2.
Toast does not necessarily need a TN tn = mTN object
when . When creating a TN object, you need to create a Handler object. But there is no Chuangjian Looper at this time,
why is there no Chuangjian Looper?
Because the main thread has already helped us create and healthy Looper, so we don't need to create health ourselves, then the problem comes, when there is no Looper object, Toast can't be used

That is, when using Toast in a child thread, we need to manually create a Looper object


Test code:

package com.example.event;

import android.os.Bundle;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class TestActivity extends AppCompatActivity {

    @BindView(R.id.textView)
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView(R.layout.activity_test);
        ButterKnife.bind(this);
        EventBus.getDefault().register(this);
        EventBus.getDefault().post(new Message("test ", 22));

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(2000);
//                } catch (InterruptedException e) {
// e.printStackTrace ();
//                }
//                EventBus.getDefault().post(new Message("hh", 22));
//            }
//        }).start();

    }



    /**
     * Solve the problem:
     * 1. The child thread can update the UI at the beginning, but cannot update the UI after a while
     * Send message in onCreate
     * EventBus.getDefault().post(new Message("test ", 22));
     * The UI can be updated in the child thread (and will not throw an exception)
     * The reason is that the ViewRootImpl class has not been created at this time, and the checkThread() method cannot be called to detect whether it is a UI thread, so the UI can be updated
     * When the button is clicked and then the message is sent
     * @Subscribe(threadMode = ThreadMode.ASYNC)
     * public void messages(final Message message){}
     * Get the object and update the UI in the child thread. At this time, the ViewRootImpl object has been created, call checkThread() to judge, and execute textView.setText(message.toString())
     * In which thread, when it is detected that it is not the main thread, the exception CalledFromWrongThreadException is thrown directly
     *
     * 2.Toast does not have to be on the main thread
     * When calling the show() method, a TN tn = mTN object is required. When creating a TN object, a Handler object needs to be created, but at this time, there is no create-health Looper
     * Why not Chuangjian Looper?
     * Because the main thread has already helped us create a healthy Looper, we don't need to create our own health, then the problem comes, when there is no Looper object, Toast can't be used
     * That is, when using Toast in a child thread, we need to manually create a Looper object
     *
     *
     * */




    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void messages(final Message message) {

        Log.i("TestActivity", Thread.currentThread().getName());
        message.toString();
        textView.setText(message.toString());


//        this.runOnUiThread(new Runnable() {
//            @Override
//            public void run() {
//                Toast.makeText(TestActivity.this,message.toString(),Toast.LENGTH_LONG).show();
//            }
//        });

//        Looper.prepare();
//        Toast.makeText(TestActivity.this,message.toString(),Toast.LENGTH_LONG).show();
//        Looper.loop();

        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(TestActivity.this,message.toString(),Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }).start();
    }


    @Override
    protected void onDestroy() {
        super.onDestroy ();
        EventBus.getDefault().unregister(this);
    }


    @OnClick(R.id.button2)
    public void onViewClicked() {
        EventBus.getDefault().post(new Message("send",20));
        //finish();
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325980830&siteId=291194637