Search code examples
javaandroidandroid-intentstart-activitystartactivityforresult

Android - A class object that belong to MainActivity not match with the sub-activity when startActivity is done


First of all, I'm new to the Android environment, so excuse me if I say something without sense.

Current Situation

I'm doing an application that have two activities: MainActivity and GraphActivity.

Also I have a class BLEConnection that I want it to know both activities. The MainActivity have only one button.

onClick() of the button:

GraphActivity graph_activity = new GraphActivity();
BLEConnection radino_right = new BLEConnection(mainThread, graph_activity);
btnConnect.setText("Connecting");

The class BLEConnection has a BluetoothGattCallback() object, and when it detects onConnectionStateChange() it calls a thread running in MainActivity.

If the Bluetooth device is connected, the String connect_status = "Connected", then this thread creates an Intent and do the startActivity().

Thread running in MainActivity:

Thread mainThread = new Thread(new Runnable() {
    @Override
    public void run() {
        if(connect_status.equals("Connected")){
            Intent nextScreen = new Intent(getApplicationContext(), ((Object) graph_activity).getClass());
            //startActivityForResult() instead of startActivity() because I want to finish() it from the MainActivity if the connection with the device is closed.
            startActivityForResult(nextScreen,1);
        }
        else{
            if(nextScreen != null){
                finishActivity(1);
            }
        }
    }
});

Troubleshoting

The troubleshooting that I am having is that I noticed that the object graph_activity that belong to MainActivity and that I passed to BLEConnection does not match with the real GraphActivity that is launched with the startActivity() method.

Does anyone know how can I solve this?

I think that if I do a "new" when I create the activity object, it generates a new thread GraphActivity, and when I call startActivity() it generates another thread of the same class, but not linked with the previously object that I created before. I don't know how to solve that.


Solution

  • Ok, I think you should refactor a bit. It is true, you create 2 different instances of graphactivity. you don't need the first one.

    You could use a singleton with listeners like this:

    1 Make BLEConnection a Singleton:

    public class BLEConnection {
        private static BLEConnection singletonInstance = new BLEConnection();
    
        private BLEConnection() {} //constructor cannot be called from outside
    
        public static BLEConnection getInstance() {
            return singletonInstance;
        }
    
        (... your Stuff here)
    }
    

    Now BLEConnection will stay in Memory and you always get the same Instance if you call

    BLEConnection bleconnection = BLEConnection.getInstance(); 
    

    from anywhere in your app.

    2 Create a listener interface:

    public interface BLEConnectionListener {
        void statusUpdated(String newStatus);
        //you can write more functions here. Every activity from step 3 has to implement them
    }
    

    3 Make your Activities implement the interface:

    public class MainActivity implements BLEConnectionListener {
        public void statusUpdated(String newStatus) {
            //do your thread thing here if you want to...
        }
    }
    
    public class GraphActivity implements BLEConnectionListener {
        public void statusUpdated(String newStatus) {
            //do graph stuff here
        }
    }
    

    4 Inform BLEConnection about the interfaces:

    MainActivity & GraphActivity in onResume / onPause:

    public void onResume() {
        // bla
        BLEConnection bleConnection = BLEConnection.getInstance(); 
        bleConnection.addListener(this);
    }
    
    public void onPause() {
        // bla
        BLEConnection bleConnection = BLEConnection.getInstance(); 
        bleConnection.removeListener(this);
    }
    

    Update BLEConnection

    public class BLEConnection {
    
        private ArrayList<BLEConnectionListener> listeners = new ArrayList<BLEConnectionListener>();
    
        public void addListener(BLEConnectionListener listener) {
            if (!listeners.contains(listener)) {
                listeners.add(listener);
            }
        }
    
        public void removeListener(BLEConnectionListener listener) {
            if (listeners.contains(listener)) {
                listeners.remove(listener);
            }
        }
    
        public void forwardStatusUpdate(String statusString) {
            for (BLEConnectionListener listener: listeners) {
                listener.statusUpdated(statusString);
            }
        }
    }
    

    I hope this is understandable. In BLEConnection, you can now call

    forwardStatusUpdate("Connected");
    

    to inform all the listeners (= active activities) about the status.