Home > Mobile >  How to fix the Issue with replacing AsyncTask to connect socket?
How to fix the Issue with replacing AsyncTask to connect socket?

Time:12-06

I'm trying to use This approach(Marked Answer) to replace my code with AsyncTask to make connection between user in android and server, And here's what I've done :

Note: I'm not using any specific pattern, just trying to achieve this goal on a basic structure.

MainActivity :

public class MainActivity extends AppCompatActivity {
    private ClientConnection connection;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        connection = new ClientConnection(inputServerIp.getText().toString(), inputUserName.getText().toString(), Integer.parseInt(inputPort.getText().toString()));
    }
}

ClientConnection :

public class ClientConnection {
    private Socket serverSocket;
    private ConnectionTask taskRunner;

    public ClientConnection(String ipAddress, String userName, int dstPort) {
        this.ipAddress = ipAddress;
        this.userName = userName;
        this.dstPort = dstPort;
    }

    public void connect() {
        taskRunner.executeAsync(new ConnectionRunningTask(ipAddress, dstPort), (data) -> {
            serverSocket = data;
        });
    }

ConnectionTask :

public class ConnectionTask {

    private final Executor executor = Executors.newSingleThreadExecutor();
    private final Handler handler = new Handler(Looper.getMainLooper());

    public interface Callback<R> {
        void onComplete(R result);
    }

    public void executeAsync(Callable<R> callable, Callback<R> callback) {
        executor.execute(() -> {
            try {
                final R result = callable.call();
                handler.post(() -> {
                    callback.onComplete(result);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}

ConnectionRunningTask:

public class ConnectionRunningTask implements Callable<Socket> {
    private final String ipAddress;
    private final Integer dstPort;

    public ConnectionRunningTask(String ipAddress, Integer dstPort) {
        this.ipAddress = ipAddress;
        this.dstPort = dstPort;
    }

    @Override
    public Socket call() throws IOException {
        return new Socket(ipAddress, dstPort);
    }
}

So base on the above code I'll try to explain what I've tried and what is the current problem :

Problem: base on the above code I'm getting the below error in connect() which it is telling me data is R and you can't set it to serverSocket, and due to this error I can't build the application.

Then I've tried to replace all R with Socket in the ConnectionTask class ( R in Callback and Callable), which in this case application was able to build and run.

public interface Callback<Socket> {
    void onComplete(Socket result);
}

public void executeAsync(Callable<Socket> callable, Callback<Socket> callback) {
    executor.execute(() -> {
        try {
            final Socket result = callable.call();
            handler.post(() -> {
                callback.onComplete(result);
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
}

But based on the above approach I'll get an error when I hit connect button, and here's what I've got :

2021-12-06 04:02:26.942 16417-16417/ir.atlaspio.atlasclientchat E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ir.atlaspio.atlasclientchat, PID: 16417
    java.lang.NullPointerException: Attempt to invoke virtual method 'void ir.atlaspio.atlasclientchat.networking.ConnectionTask.executeAsync(java.util.concurrent.Callable, ir.atlaspio.atlasclientchat.networking.ConnectionTask$Callback)' on a null object reference
        at ir.atlaspio.atlasclientchat.networking.ClientConnection.connect(ClientConnection.java:38)
        at ir.atlaspio.atlasclientchat.MainActivity$1.onClick(MainActivity.java:61)
        at android.view.View.performClick(View.java:4780)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View$PerformClick.run(View.java:19866)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
2021-12-06 04:07:27.221 16417-16417/ir.atlaspio.atlasclientchat I/Process: Sending signal. PID: 16417 SIG: 9

On the Server-Side I've also checked incoming connections, and nothing happened there...

CodePudding user response:

You're not instantiating taskRunner inside ClientConnection. Add this line to the constructor:

public ClientConnection(String ipAddress, String userName, int dstPort) {
    this.ipAddress = ipAddress;
    this.userName = userName;
    this.dstPort = dstPort;
    this.taskRunner = new ConnectionTask(); // <-- this line here
}
  • Related