简体   繁体   中英

Android communication between main thread and other thread

I want to change dynamically the text of a textview, but I will need the same logic if I want to make a game thread, so I need to make the communication between the main one and the second one.

I have the files :

MainActivity

public class MainActivity extends ActionBarActivity {

    public static Handler mHandler;
    Runnable thread = new SampleThread();
    TextView txt1 = (TextView) findViewById(R.id.txt1);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActionBar actionBar = getSupportActionBar();
        actionBar.hide();

        //hiding status bar
        if (Build.VERSION.SDK_INT < 16) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
        } else {
            View decorView = getWindow().getDecorView();
            int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(uiOptions);
        }
        setContentView(R.layout.activity_main);


        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
                // i want to change the text of txt1 here
            }
        };
        new Thread(thread).start();


    }
}

SampleThread

package com.example.katsar0v.myapplication;

import android.util.Log;

/**
 * Created by Katsar0v on 1/21/2015.
 */
public class SampleThread implements Runnable {

    @Override
    public void run() {
        int two = 0;
        while(two<10) {
            two++;
            try {
                Thread.sleep(1000);

                //instead of logging, i want to send the text to main UI
                Log.d("MSG", String.valueOf(two + "sec"));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

The problem I see is, how do I change the text with the handler, when my thread is in another file? Or should I make the second class static within the first one (and what should I do when the code gets really long, it can't be all in one file)?

You could implement a custom Interface in order to handle it from your main activity. On your SampleThread :

public interface TextViewChangeListener
{
    public void onTextViewChanged(String newName);
}
TextViewChangeListener mListener;

Then call mListener.onTextViewChanged(String newName) wherever you want to have the new name in your TextView . Remember to initialize mListener with an instance of your MainActivity first, otherwise you will get a null pointer exception. You can do that either in the constructor of SampleThread or by creating a method for the purpose.

In your activity you should implement SampleThread.TextViewChangeListener and override the onTextViewChanged .

@Override
public void onTextViewChanged(String newName)
{
   //MyTextView.setText(newName);
}

Edit : untested code: MainActivity:

public class MainActivity extends ActionBarActivity implements SampleThread.TextViewChangeListener {
@Override
public void onTextViewChanged(Message msg)
{
    // process incoming messages here
    // i want to change the text of txt1 here
}

public static Handler mHandler;
Runnable thread = new SampleThread(this);
TextView txt1 = (TextView) findViewById(R.id.txt1);
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();

    //hiding status bar
    if (Build.VERSION.SDK_INT < 16) {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    } else {
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);
    }
    setContentView(R.layout.activity_main);
    new Thread(thread).start();
}
}

SampleThread:

package com.example.katsar0v.myapplication;
import android.util.Log; 
/**
* Created by Katsar0v on 1/21/2015.
*/
public class SampleThread implements Runnable 
{
public interface TextViewChangeListener
{
    public void onTextViewChanged(Message msg);
}

public SampleThread(TextViewChangeListener mListener)
{
    this.mListener = mListener;
}

TextViewChangeListener mListener;

@Override
public void run() {
    int two = 0;
    while(two<10) {
        two++;
        try {
            Thread.sleep(1000);
            mListener.onTextViewChanged(String.valueOf(two + "sec"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}

Let me know if that helped.

You can find some examples in Grafika , which does a lot of work off the UI thread. For example, TextureFromCameraActivity has a pair of handlers, one for the UI thread, one for the renderer thread. In onResume() you can see the main thread passing its handler to the renderer through a constructor, then retrieving the renderer thread's handler with a method call.

ContinuousCaptureActivity has a slightly different approach, using a Handler that also implements a callback interface. The handler object is passed to the CircularEncoder constructor as an interface instance. The public callback methods use the Handler internally.

The only tricky bit is if you're passing a Handler out of the non-UI thread. You either need to do it before the thread starts, or use appropriate thread synchronization operations to avoid data races .

You don't need to have your classes in the same file (and you really shouldn't unless one is nested inside the other). If they're in the same package then the default (package) scope will let them see each other. The first example from Grafika uses nested / private classes, the second example is more spread out.

Of course, if all you're trying to do is submit UI events from a non-UI thread, you can just use Activity.runOnUiThread() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM