Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
492 views
in Technique[技术] by (71.8m points)

android - How to notify an activity when GlobalVariables are changed

I have an android application that is connected to the computer via USB cable. I use a TCPServer Class to send messages and listen. For example:

When I send a message like: request:x
I get the response: response:x:55

I need to make changes on my activity according to the response I get. At the moment I temporarily solved the problem by passing activity and activity class object to the TCPServer's constructor

public TCPServer(int portNum, Activity activity, IntroActivity ia) {
    super();
    port = portNum;
    this.activity = activity;
    this.ia = ia;
}    

Then after I receive the response:

void updateButton(final int color, final String txt) {
    activity.runOnUiThread(new Runnable() {
         public void run() {
             ia.getConnectionButton().setBackgroundColor(color);
             ia.getConnectionButton().setText(txt);
        }
    });
}   

As you see, this is not effective at all. I need to somehow notify the activity whenever a relevant variable is received. I use a Class for GlobalVariables and change those static variables after listen(), however I am having troubles notifying the activity.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First of all, it is almost always bad practice to pass Activity instances around. This is a time when it's bad.

Define an interface and use a callback to let the activity know that a response has been received.

public interface ResponseReceivedListener {
    void onResponseReceived(int arg1, string arg2); // <- add arguments you want to pass back
}

In your TCPServer class:

ArrayList<ResponseReceivedListener> listeners = new ArrayList<>();

// ...

public void setResponseReceivedListener(ResponseReceivedListener listener) {
    if (!listeners.contains(listener) {
        listeners.add(listener);
    }
}

public void removeResponseReceivedListener(ResponseReceivedListener listener) {
    if (listeners.contains(listener) {
        listeners.remove(listener);
    }
}

When you receive a response:

for (ResponseReceivedListener listener : listeners) {
   listener.onResponseReceived(arg1, arg2);
}

In your Activity:

public class MainActivity extends Activity implements ResponseReceivedListener {

    // ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // ...

        tcpServer.setResponseReceivedListener(this);

        // ...
    }

    public void onResponseReceived(int arg1, string arg2) {
        // do whatever you need to do
    }

    // ...
}

All from memory so please excuse typos.

This approach decouples the classes. The TCP Server has no knowledge of the activities. It simply calls back to any listeners registered. Those listeners might be Activities, they might be services. They might be instances of MySparklyUnicorn. The server neither knows nor cares. It simply says "if anyone's interested, I've received a response and here are the details".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...