0

I was trying to pass my socket connection from one activity to another. Here is my code snippet.

public class MainActivity extends AppCompatActivity {

            //private EditText serverIp;

            private Button connectPhones;

            protected String SERVER_IP_ADDR = "172.16.1.103";

            protected String SERVER_PORT = "8889";

            private boolean connected = false;

            private Handler handler = new Handler();

            Socket socket;

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

                //serverIp = (EditText) findViewById(R.id.server_ip);
                connectPhones = (Button) findViewById(R.id.connect);
                connectPhones.setOnClickListener(connectListener);
            }


            public Socket getSocket(){
                Log.wtf("MainActivity : ",socket.toString());
                return socket;
            }

            private View.OnClickListener connectListener = new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    if (!connected) {
                        //SERVER_IP_ADDR = SERVER_IP_ADDR.getText().toString();
                        if (!SERVER_IP_ADDR.equals("")) {
                            Thread cThread = new Thread(new ClientThread());
                            cThread.start();
                        }
                    }
                }
            };

            public class ClientThread implements Runnable {

                public void run() {
                    try {
                        InetAddress serverAddr = InetAddress.getByName(SERVER_IP_ADDR);
                        Log.d("ClientActivity", "C: Connecting...");
                        socket = new Socket(serverAddr, Integer.parseInt(SERVER_PORT));
                        connected = true;

                            try {
                                Log.d("ClientActivity", "C: Sending command.");
                                PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                                        .getOutputStream())), true);
                                out.println("Hey Server!");
                                Log.d("ClientActivity", "C: Sent.");
                                Intent intent = new Intent(getApplicationContext(), SocketInteraction.class);
                                startActivityForResult(intent,1);
                            } catch (Exception e) {
                                Log.e("ClientActivity", "S: Error", e);
                            }

                        //socket.close();
                        Log.d("ClientActivity", "C: Closed.");
                    } catch (Exception e) {
                        Log.e("ClientActivity", "C: Error", e);
                        connected = false;
                    }
                }

            }
        }

And in other activity, I am calling it like this

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.socketinteraction);
    MainActivity mainActivity = new MainActivity();
    final Socket socket = mainActivity.getSocket();   //returns null pointer

But I don't know why, Its returning a Nullpointerexception. Can someone please assist me on how should I deal with this ?

user207421
  • 305,947
  • 44
  • 307
  • 483
Panda
  • 2,400
  • 3
  • 25
  • 35
  • You cannot instantiate an `Activity` with `new` and have it work correctly. Even if you could, the new instance would not have the same `Socket` created in the previous instance. – Mike M. Apr 10 '16 at 05:11
  • have you solved the problem? – Pooya Apr 18 '16 at 05:20
  • I have upvoted your answer, I have not tried it yet! So will mark it correct, once I get back. – Panda Apr 18 '16 at 13:03

3 Answers3

1

You need to use Singleton patterns class like the following:

public class SocketSingleton {


private static Socket socket;

public static void setSocket(Socket _socket){
    SocketSingleton.socket=_socket;
}

public static Socket getSocket(){
    return SocketSingleton.socket;
}

and then in your MainActivity use the following:

SocketSingleton.setSocket(socket);
Intent i = new Intent(getActivity().getApplicationContext(), NewActivity.class);
startActivity(intent);

and finally in your NewActivity use the following:

Socket socket = SocketSingleton.getSocket();
Pooya
  • 6,083
  • 3
  • 23
  • 43
  • Hi, I dont get the singleton patterns class part. Do I create it in a new java file? Or place it together with the activity that will establish the server? – mctjl_1997 May 22 '17 at 07:02
  • Each public concrete class need to be in a separate .java file – Pooya May 22 '17 at 15:55
0

I am sorry to say this, but your code is a total mess,

Reasons

  1. We should not create an instance of an activity, its the job of android framework to create, we can only start an activity.

  2. The second activity has a different layout 'socketinteraction', and the code to create socket is written in the button click listener, which is in your MainActivity layout.

You might want to do something like this,

From your other activity,

  1. Add a button in your layout 'socketinteraction'
  2. On click of the button,start mainactivity like below,

    startActivityForResult(new Intent(this,MainActivity.class),0)

and always use Intent to communicate between activities. Refer this link, http://developer.android.com/training/basics/intents/result.html

  1. Do your task in MainActivity, and once your job is done, set the Result using setResult method,

Refer to this link,

http://stackoverflow.com/questions/920306/sending-data-back-to-the-main-activity-in-android

Thiyaga B
  • 971
  • 1
  • 9
  • 26
  • Thank you for your kind suggestion, However, my question is not answered. – Panda Apr 10 '16 at 13:29
  • As I have mentioned the socket is created only in the thread, so when you create a new MainActivity the default value of the socket object is return which is null, you may call the thread from the MainActivity constructor and still you can access the socket object only the thread creates it – Thiyaga B Apr 10 '16 at 14:55
0

You can do it quite easily, create and instance of your MainActivity like this.

    public class MainActivity extends Activity {
        public static MainActivity sInstance = null;

        protected void onCreate(Bundle bundle) {
             super.onCreate(...);
             setContentView(...);
             sInstance = this;
        }
    }

Now in your other activity you can call it simply like this.

    if (MainActivity.sInstance != null) {
         final Socket socket = MainActivity.sInstance.getSocket();
    }

this creates your MainActivity a Singleton while its running. Just don't finish it when you go to the next Activity and when you are done and when you are shutting your app down. Release the sInstance like this, Don't forget this part.

    sInstance = null;
Muneeb Ahmad
  • 134
  • 4