Is using AsyncTask in a multi-user chat Android client better than extending a connection thread?










0














I'm practicing multi-client networking using a Java Server and Android clients. I have done this with Java clients before so I adapted my solution mostly around what I know in Java using multithreading. Which is extending a thread for each client connection created. I usually have a separate ClientConnection class in Java but here I used a protected inner class.



This solution works but someone mentioned to me that I might want to do this with AsyncTask rather. What benefits would using AsyncTask offer rather than extending a thread the way I have done here?



Please note I am not asking for any code or how I would go about doing it. Just what benefits it would offer over this method.



Client Layout



<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="za.ac.nmu.wrap302.jan2015.MainActivity">

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/loginPanel"
android:layout_alignParentBottom="true">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/etHandle"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect"
android:id="@+id/btnConnect"
android:layout_below="@+id/etHandle"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/etHandle"
android:layout_alignEnd="@+id/etHandle"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/chatPanel"
android:visibility="gone">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lvMessages"
android:layout_below="@+id/btnConnect"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="@+id/txtMessage"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Change Room"
android:id="@+id/btnRoom"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/txtMessage"
android:layout_above="@+id/btnDisconnect"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/btnDisconnect"
android:layout_alignEnd="@+id/btnDisconnect"/>
</LinearLayout>
<LinearLayout
android:background="?android:colorBackground"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/roomPanel"
android:visibility="gone">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Disconnect"
android:id="@+id/btnDisconnect"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/lvMessages"
android:layout_alignEnd="@+id/lvMessages"/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lvRooms"/>
</LinearLayout>




Client Code



public class MainActivity extends AppCompatActivity 
EditText etHandle;
ConnectionThread connectionThread;
private ArrayList<String> messages;
private ArrayAdapter<String> adapter;

private ArrayList<String> rooms;
private ArrayAdapter<String> roomsAdapter;

private static final String SET_HANDLE = "#SetHandle";
private static final String SEND_MESSAGE = "#SendMessage";
private static final String DISCONNECT = "#Disconnect";
private static final String JOIN_ROOM = "#JoinRoom";
private static final String LIST_ROOMS = "#ListRooms";

ListView lvMessages;
ListView lvRooms;

EditText textMessage;
Button btnConnect;
Button btnDisconnect;
Button btnRoom;
LinearLayout chatPanel, roomPanel, loginPanel;

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

etHandle = (EditText) findViewById(R.id.etHandle);
lvMessages = (ListView) findViewById(R.id.lvMessages);
textMessage = (EditText) findViewById(R.id.txtMessage);
btnConnect = (Button) findViewById(R.id.btnConnect);
btnDisconnect = (Button) findViewById(R.id.btnDisconnect);
chatPanel = (LinearLayout) findViewById(R.id.chatPanel);
roomPanel = (LinearLayout) findViewById(R.id.roomPanel);
loginPanel = (LinearLayout) findViewById(R.id.loginPanel);
lvRooms = (ListView) findViewById(R.id.lvRooms);
btnRoom = (Button) findViewById(R.id.btnRoom);

messages = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_selectable_list_item, messages);
lvMessages.setAdapter(adapter);

rooms = new ArrayList<String>();
roomsAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_selectable_list_item, rooms);
lvRooms.setAdapter(roomsAdapter);

btnConnect.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
connectionThread = new ConnectionThread(etHandle.getText().toString());
connectionThread.start();

);

btnDisconnect.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Thread out = new Thread(new Runnable()
@Override
public void run()
try
connectionThread.out.writeUTF(DISCONNECT);
catch (IOException e)
e.printStackTrace();


);
out.start();
hideRoomScreen();
showLoginScreen();

);

btnRoom.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
showRoomScreen();
Thread out = new Thread(new Runnable()
@Override
public void run()
try
connectionThread.out.writeUTF(LIST_ROOMS);
catch (IOException e)
e.printStackTrace();


);
out.start();

);

textMessage.setOnKeyListener(new View.OnKeyListener()
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
if ((keyCode == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
final String text = textMessage.getText().toString();
Thread out = new Thread(new Runnable()
@Override
public void run()
try
connectionThread.out.writeUTF(SEND_MESSAGE);
connectionThread.out.writeUTF(text);
catch (IOException e)
e.printStackTrace();


);
out.start();
textMessage.getText().clear();
return true;

return false;

);

lvRooms.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
final String roomName = roomsAdapter.getItem(i);
Thread out = new Thread(new Runnable()
@Override
public void run()
try
connectionThread.out.writeUTF(JOIN_ROOM);
connectionThread.out.writeUTF(roomName);
catch (IOException e)
e.printStackTrace();


);
out.start();
hideRoomScreen();
showChatScreen();

);


public void addMessage(String message)
adapter.add(message);
lvMessages.setSelection(adapter.getCount() - 1);


public void addRoom(final String roomName)
runOnUiThread(new Runnable()
@Override
public void run()
roomsAdapter.add(roomName);

);


protected class ConnectionThread extends Thread
Socket connection;
DataInputStream in;
DataOutputStream out;
String handle;
boolean connected;

public ConnectionThread(String name)
handle = name;


@Override
public void run()
try
connection = new Socket("10.0.0.10", 1234);
connected = true;

in = new DataInputStream(connection.getInputStream());
out = new DataOutputStream(connection.getOutputStream());

out.writeUTF(handle);

hideLoginScreen();
btnRoom.callOnClick();

String command = "";
while (connected)
command = in.readUTF();
switch (command)
case SEND_MESSAGE:
final String user = in.readUTF();
final String message = in.readUTF();
runOnUiThread(new Runnable()
@Override
public void run()
addMessage(user + ": " + message);

);
break;
case DISCONNECT:
showLoginScreen();
connected = false;
break;
case LIST_ROOMS:
int count = in.readInt();
runOnUiThread(new Runnable()
@Override
public void run()
roomsAdapter.clear();

);
for(int i = 0; i < count; i++)
String roomName = in.readUTF();
addRoom(roomName);

break;



catch (IOException e)
e.printStackTrace();





private void showLoginScreen()
runOnUiThread(new Runnable()
@Override
public void run()
loginPanel.setVisibility(View.VISIBLE);

);


private void hideLoginScreen()
runOnUiThread(new Runnable()
@Override
public void run()
loginPanel.setVisibility(View.GONE);

);


private void showChatScreen()
runOnUiThread(new Runnable()
@Override
public void run()
chatPanel.setVisibility(View.VISIBLE);

);


private void hideChatScreen()
runOnUiThread(new Runnable()
@Override
public void run()
chatPanel.setVisibility(View.GONE);

);


private void showRoomScreen()
runOnUiThread(new Runnable()
@Override
public void run()
roomPanel.setVisibility(View.VISIBLE);

);


private void hideRoomScreen()
runOnUiThread(new Runnable()
@Override
public void run()
roomPanel.setVisibility(View.GONE);

);












share|improve this question


























    0














    I'm practicing multi-client networking using a Java Server and Android clients. I have done this with Java clients before so I adapted my solution mostly around what I know in Java using multithreading. Which is extending a thread for each client connection created. I usually have a separate ClientConnection class in Java but here I used a protected inner class.



    This solution works but someone mentioned to me that I might want to do this with AsyncTask rather. What benefits would using AsyncTask offer rather than extending a thread the way I have done here?



    Please note I am not asking for any code or how I would go about doing it. Just what benefits it would offer over this method.



    Client Layout



    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="za.ac.nmu.wrap302.jan2015.MainActivity">

    <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/loginPanel"
    android:layout_alignParentBottom="true">
    <EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/etHandle"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"/>
    <Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Connect"
    android:id="@+id/btnConnect"
    android:layout_below="@+id/etHandle"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignRight="@+id/etHandle"
    android:layout_alignEnd="@+id/etHandle"/>
    </LinearLayout>
    <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/chatPanel"
    android:visibility="gone">
    <ListView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/lvMessages"
    android:layout_below="@+id/btnConnect"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_above="@+id/txtMessage"/>
    <Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Change Room"
    android:id="@+id/btnRoom"/>
    <EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/txtMessage"
    android:layout_above="@+id/btnDisconnect"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignRight="@+id/btnDisconnect"
    android:layout_alignEnd="@+id/btnDisconnect"/>
    </LinearLayout>
    <LinearLayout
    android:background="?android:colorBackground"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/roomPanel"
    android:visibility="gone">
    <Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Disconnect"
    android:id="@+id/btnDisconnect"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignRight="@+id/lvMessages"
    android:layout_alignEnd="@+id/lvMessages"/>
    <ListView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/lvRooms"/>
    </LinearLayout>




    Client Code



    public class MainActivity extends AppCompatActivity 
    EditText etHandle;
    ConnectionThread connectionThread;
    private ArrayList<String> messages;
    private ArrayAdapter<String> adapter;

    private ArrayList<String> rooms;
    private ArrayAdapter<String> roomsAdapter;

    private static final String SET_HANDLE = "#SetHandle";
    private static final String SEND_MESSAGE = "#SendMessage";
    private static final String DISCONNECT = "#Disconnect";
    private static final String JOIN_ROOM = "#JoinRoom";
    private static final String LIST_ROOMS = "#ListRooms";

    ListView lvMessages;
    ListView lvRooms;

    EditText textMessage;
    Button btnConnect;
    Button btnDisconnect;
    Button btnRoom;
    LinearLayout chatPanel, roomPanel, loginPanel;

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

    etHandle = (EditText) findViewById(R.id.etHandle);
    lvMessages = (ListView) findViewById(R.id.lvMessages);
    textMessage = (EditText) findViewById(R.id.txtMessage);
    btnConnect = (Button) findViewById(R.id.btnConnect);
    btnDisconnect = (Button) findViewById(R.id.btnDisconnect);
    chatPanel = (LinearLayout) findViewById(R.id.chatPanel);
    roomPanel = (LinearLayout) findViewById(R.id.roomPanel);
    loginPanel = (LinearLayout) findViewById(R.id.loginPanel);
    lvRooms = (ListView) findViewById(R.id.lvRooms);
    btnRoom = (Button) findViewById(R.id.btnRoom);

    messages = new ArrayList<String>();
    adapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_selectable_list_item, messages);
    lvMessages.setAdapter(adapter);

    rooms = new ArrayList<String>();
    roomsAdapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_selectable_list_item, rooms);
    lvRooms.setAdapter(roomsAdapter);

    btnConnect.setOnClickListener(new View.OnClickListener()
    @Override
    public void onClick(View view)
    connectionThread = new ConnectionThread(etHandle.getText().toString());
    connectionThread.start();

    );

    btnDisconnect.setOnClickListener(new View.OnClickListener()
    @Override
    public void onClick(View view)
    Thread out = new Thread(new Runnable()
    @Override
    public void run()
    try
    connectionThread.out.writeUTF(DISCONNECT);
    catch (IOException e)
    e.printStackTrace();


    );
    out.start();
    hideRoomScreen();
    showLoginScreen();

    );

    btnRoom.setOnClickListener(new View.OnClickListener()
    @Override
    public void onClick(View view)
    showRoomScreen();
    Thread out = new Thread(new Runnable()
    @Override
    public void run()
    try
    connectionThread.out.writeUTF(LIST_ROOMS);
    catch (IOException e)
    e.printStackTrace();


    );
    out.start();

    );

    textMessage.setOnKeyListener(new View.OnKeyListener()
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event)
    if ((keyCode == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
    final String text = textMessage.getText().toString();
    Thread out = new Thread(new Runnable()
    @Override
    public void run()
    try
    connectionThread.out.writeUTF(SEND_MESSAGE);
    connectionThread.out.writeUTF(text);
    catch (IOException e)
    e.printStackTrace();


    );
    out.start();
    textMessage.getText().clear();
    return true;

    return false;

    );

    lvRooms.setOnItemClickListener(new AdapterView.OnItemClickListener()
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
    final String roomName = roomsAdapter.getItem(i);
    Thread out = new Thread(new Runnable()
    @Override
    public void run()
    try
    connectionThread.out.writeUTF(JOIN_ROOM);
    connectionThread.out.writeUTF(roomName);
    catch (IOException e)
    e.printStackTrace();


    );
    out.start();
    hideRoomScreen();
    showChatScreen();

    );


    public void addMessage(String message)
    adapter.add(message);
    lvMessages.setSelection(adapter.getCount() - 1);


    public void addRoom(final String roomName)
    runOnUiThread(new Runnable()
    @Override
    public void run()
    roomsAdapter.add(roomName);

    );


    protected class ConnectionThread extends Thread
    Socket connection;
    DataInputStream in;
    DataOutputStream out;
    String handle;
    boolean connected;

    public ConnectionThread(String name)
    handle = name;


    @Override
    public void run()
    try
    connection = new Socket("10.0.0.10", 1234);
    connected = true;

    in = new DataInputStream(connection.getInputStream());
    out = new DataOutputStream(connection.getOutputStream());

    out.writeUTF(handle);

    hideLoginScreen();
    btnRoom.callOnClick();

    String command = "";
    while (connected)
    command = in.readUTF();
    switch (command)
    case SEND_MESSAGE:
    final String user = in.readUTF();
    final String message = in.readUTF();
    runOnUiThread(new Runnable()
    @Override
    public void run()
    addMessage(user + ": " + message);

    );
    break;
    case DISCONNECT:
    showLoginScreen();
    connected = false;
    break;
    case LIST_ROOMS:
    int count = in.readInt();
    runOnUiThread(new Runnable()
    @Override
    public void run()
    roomsAdapter.clear();

    );
    for(int i = 0; i < count; i++)
    String roomName = in.readUTF();
    addRoom(roomName);

    break;



    catch (IOException e)
    e.printStackTrace();





    private void showLoginScreen()
    runOnUiThread(new Runnable()
    @Override
    public void run()
    loginPanel.setVisibility(View.VISIBLE);

    );


    private void hideLoginScreen()
    runOnUiThread(new Runnable()
    @Override
    public void run()
    loginPanel.setVisibility(View.GONE);

    );


    private void showChatScreen()
    runOnUiThread(new Runnable()
    @Override
    public void run()
    chatPanel.setVisibility(View.VISIBLE);

    );


    private void hideChatScreen()
    runOnUiThread(new Runnable()
    @Override
    public void run()
    chatPanel.setVisibility(View.GONE);

    );


    private void showRoomScreen()
    runOnUiThread(new Runnable()
    @Override
    public void run()
    roomPanel.setVisibility(View.VISIBLE);

    );


    private void hideRoomScreen()
    runOnUiThread(new Runnable()
    @Override
    public void run()
    roomPanel.setVisibility(View.GONE);

    );












    share|improve this question
























      0












      0








      0







      I'm practicing multi-client networking using a Java Server and Android clients. I have done this with Java clients before so I adapted my solution mostly around what I know in Java using multithreading. Which is extending a thread for each client connection created. I usually have a separate ClientConnection class in Java but here I used a protected inner class.



      This solution works but someone mentioned to me that I might want to do this with AsyncTask rather. What benefits would using AsyncTask offer rather than extending a thread the way I have done here?



      Please note I am not asking for any code or how I would go about doing it. Just what benefits it would offer over this method.



      Client Layout



      <RelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:paddingLeft="@dimen/activity_horizontal_margin"
      android:paddingRight="@dimen/activity_horizontal_margin"
      android:paddingTop="@dimen/activity_vertical_margin"
      android:paddingBottom="@dimen/activity_vertical_margin"
      tools:context="za.ac.nmu.wrap302.jan2015.MainActivity">

      <LinearLayout
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/loginPanel"
      android:layout_alignParentBottom="true">
      <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/etHandle"
      android:layout_alignParentTop="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignParentRight="true"
      android:layout_alignParentEnd="true"/>
      <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="Connect"
      android:id="@+id/btnConnect"
      android:layout_below="@+id/etHandle"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignRight="@+id/etHandle"
      android:layout_alignEnd="@+id/etHandle"/>
      </LinearLayout>
      <LinearLayout
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/chatPanel"
      android:visibility="gone">
      <ListView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/lvMessages"
      android:layout_below="@+id/btnConnect"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_above="@+id/txtMessage"/>
      <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="Change Room"
      android:id="@+id/btnRoom"/>
      <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/txtMessage"
      android:layout_above="@+id/btnDisconnect"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignRight="@+id/btnDisconnect"
      android:layout_alignEnd="@+id/btnDisconnect"/>
      </LinearLayout>
      <LinearLayout
      android:background="?android:colorBackground"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/roomPanel"
      android:visibility="gone">
      <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="Disconnect"
      android:id="@+id/btnDisconnect"
      android:layout_alignParentBottom="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignRight="@+id/lvMessages"
      android:layout_alignEnd="@+id/lvMessages"/>
      <ListView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/lvRooms"/>
      </LinearLayout>




      Client Code



      public class MainActivity extends AppCompatActivity 
      EditText etHandle;
      ConnectionThread connectionThread;
      private ArrayList<String> messages;
      private ArrayAdapter<String> adapter;

      private ArrayList<String> rooms;
      private ArrayAdapter<String> roomsAdapter;

      private static final String SET_HANDLE = "#SetHandle";
      private static final String SEND_MESSAGE = "#SendMessage";
      private static final String DISCONNECT = "#Disconnect";
      private static final String JOIN_ROOM = "#JoinRoom";
      private static final String LIST_ROOMS = "#ListRooms";

      ListView lvMessages;
      ListView lvRooms;

      EditText textMessage;
      Button btnConnect;
      Button btnDisconnect;
      Button btnRoom;
      LinearLayout chatPanel, roomPanel, loginPanel;

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

      etHandle = (EditText) findViewById(R.id.etHandle);
      lvMessages = (ListView) findViewById(R.id.lvMessages);
      textMessage = (EditText) findViewById(R.id.txtMessage);
      btnConnect = (Button) findViewById(R.id.btnConnect);
      btnDisconnect = (Button) findViewById(R.id.btnDisconnect);
      chatPanel = (LinearLayout) findViewById(R.id.chatPanel);
      roomPanel = (LinearLayout) findViewById(R.id.roomPanel);
      loginPanel = (LinearLayout) findViewById(R.id.loginPanel);
      lvRooms = (ListView) findViewById(R.id.lvRooms);
      btnRoom = (Button) findViewById(R.id.btnRoom);

      messages = new ArrayList<String>();
      adapter = new ArrayAdapter<String>(this,
      android.R.layout.simple_selectable_list_item, messages);
      lvMessages.setAdapter(adapter);

      rooms = new ArrayList<String>();
      roomsAdapter = new ArrayAdapter<String>(this,
      android.R.layout.simple_selectable_list_item, rooms);
      lvRooms.setAdapter(roomsAdapter);

      btnConnect.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View view)
      connectionThread = new ConnectionThread(etHandle.getText().toString());
      connectionThread.start();

      );

      btnDisconnect.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View view)
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(DISCONNECT);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();
      hideRoomScreen();
      showLoginScreen();

      );

      btnRoom.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View view)
      showRoomScreen();
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(LIST_ROOMS);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();

      );

      textMessage.setOnKeyListener(new View.OnKeyListener()
      @Override
      public boolean onKey(View v, int keyCode, KeyEvent event)
      if ((keyCode == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
      final String text = textMessage.getText().toString();
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(SEND_MESSAGE);
      connectionThread.out.writeUTF(text);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();
      textMessage.getText().clear();
      return true;

      return false;

      );

      lvRooms.setOnItemClickListener(new AdapterView.OnItemClickListener()
      @Override
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
      final String roomName = roomsAdapter.getItem(i);
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(JOIN_ROOM);
      connectionThread.out.writeUTF(roomName);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();
      hideRoomScreen();
      showChatScreen();

      );


      public void addMessage(String message)
      adapter.add(message);
      lvMessages.setSelection(adapter.getCount() - 1);


      public void addRoom(final String roomName)
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomsAdapter.add(roomName);

      );


      protected class ConnectionThread extends Thread
      Socket connection;
      DataInputStream in;
      DataOutputStream out;
      String handle;
      boolean connected;

      public ConnectionThread(String name)
      handle = name;


      @Override
      public void run()
      try
      connection = new Socket("10.0.0.10", 1234);
      connected = true;

      in = new DataInputStream(connection.getInputStream());
      out = new DataOutputStream(connection.getOutputStream());

      out.writeUTF(handle);

      hideLoginScreen();
      btnRoom.callOnClick();

      String command = "";
      while (connected)
      command = in.readUTF();
      switch (command)
      case SEND_MESSAGE:
      final String user = in.readUTF();
      final String message = in.readUTF();
      runOnUiThread(new Runnable()
      @Override
      public void run()
      addMessage(user + ": " + message);

      );
      break;
      case DISCONNECT:
      showLoginScreen();
      connected = false;
      break;
      case LIST_ROOMS:
      int count = in.readInt();
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomsAdapter.clear();

      );
      for(int i = 0; i < count; i++)
      String roomName = in.readUTF();
      addRoom(roomName);

      break;



      catch (IOException e)
      e.printStackTrace();





      private void showLoginScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      loginPanel.setVisibility(View.VISIBLE);

      );


      private void hideLoginScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      loginPanel.setVisibility(View.GONE);

      );


      private void showChatScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      chatPanel.setVisibility(View.VISIBLE);

      );


      private void hideChatScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      chatPanel.setVisibility(View.GONE);

      );


      private void showRoomScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomPanel.setVisibility(View.VISIBLE);

      );


      private void hideRoomScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomPanel.setVisibility(View.GONE);

      );












      share|improve this question













      I'm practicing multi-client networking using a Java Server and Android clients. I have done this with Java clients before so I adapted my solution mostly around what I know in Java using multithreading. Which is extending a thread for each client connection created. I usually have a separate ClientConnection class in Java but here I used a protected inner class.



      This solution works but someone mentioned to me that I might want to do this with AsyncTask rather. What benefits would using AsyncTask offer rather than extending a thread the way I have done here?



      Please note I am not asking for any code or how I would go about doing it. Just what benefits it would offer over this method.



      Client Layout



      <RelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:paddingLeft="@dimen/activity_horizontal_margin"
      android:paddingRight="@dimen/activity_horizontal_margin"
      android:paddingTop="@dimen/activity_vertical_margin"
      android:paddingBottom="@dimen/activity_vertical_margin"
      tools:context="za.ac.nmu.wrap302.jan2015.MainActivity">

      <LinearLayout
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/loginPanel"
      android:layout_alignParentBottom="true">
      <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/etHandle"
      android:layout_alignParentTop="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignParentRight="true"
      android:layout_alignParentEnd="true"/>
      <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="Connect"
      android:id="@+id/btnConnect"
      android:layout_below="@+id/etHandle"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignRight="@+id/etHandle"
      android:layout_alignEnd="@+id/etHandle"/>
      </LinearLayout>
      <LinearLayout
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/chatPanel"
      android:visibility="gone">
      <ListView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/lvMessages"
      android:layout_below="@+id/btnConnect"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_above="@+id/txtMessage"/>
      <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="Change Room"
      android:id="@+id/btnRoom"/>
      <EditText
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/txtMessage"
      android:layout_above="@+id/btnDisconnect"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignRight="@+id/btnDisconnect"
      android:layout_alignEnd="@+id/btnDisconnect"/>
      </LinearLayout>
      <LinearLayout
      android:background="?android:colorBackground"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/roomPanel"
      android:visibility="gone">
      <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="Disconnect"
      android:id="@+id/btnDisconnect"
      android:layout_alignParentBottom="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_alignRight="@+id/lvMessages"
      android:layout_alignEnd="@+id/lvMessages"/>
      <ListView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/lvRooms"/>
      </LinearLayout>




      Client Code



      public class MainActivity extends AppCompatActivity 
      EditText etHandle;
      ConnectionThread connectionThread;
      private ArrayList<String> messages;
      private ArrayAdapter<String> adapter;

      private ArrayList<String> rooms;
      private ArrayAdapter<String> roomsAdapter;

      private static final String SET_HANDLE = "#SetHandle";
      private static final String SEND_MESSAGE = "#SendMessage";
      private static final String DISCONNECT = "#Disconnect";
      private static final String JOIN_ROOM = "#JoinRoom";
      private static final String LIST_ROOMS = "#ListRooms";

      ListView lvMessages;
      ListView lvRooms;

      EditText textMessage;
      Button btnConnect;
      Button btnDisconnect;
      Button btnRoom;
      LinearLayout chatPanel, roomPanel, loginPanel;

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

      etHandle = (EditText) findViewById(R.id.etHandle);
      lvMessages = (ListView) findViewById(R.id.lvMessages);
      textMessage = (EditText) findViewById(R.id.txtMessage);
      btnConnect = (Button) findViewById(R.id.btnConnect);
      btnDisconnect = (Button) findViewById(R.id.btnDisconnect);
      chatPanel = (LinearLayout) findViewById(R.id.chatPanel);
      roomPanel = (LinearLayout) findViewById(R.id.roomPanel);
      loginPanel = (LinearLayout) findViewById(R.id.loginPanel);
      lvRooms = (ListView) findViewById(R.id.lvRooms);
      btnRoom = (Button) findViewById(R.id.btnRoom);

      messages = new ArrayList<String>();
      adapter = new ArrayAdapter<String>(this,
      android.R.layout.simple_selectable_list_item, messages);
      lvMessages.setAdapter(adapter);

      rooms = new ArrayList<String>();
      roomsAdapter = new ArrayAdapter<String>(this,
      android.R.layout.simple_selectable_list_item, rooms);
      lvRooms.setAdapter(roomsAdapter);

      btnConnect.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View view)
      connectionThread = new ConnectionThread(etHandle.getText().toString());
      connectionThread.start();

      );

      btnDisconnect.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View view)
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(DISCONNECT);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();
      hideRoomScreen();
      showLoginScreen();

      );

      btnRoom.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View view)
      showRoomScreen();
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(LIST_ROOMS);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();

      );

      textMessage.setOnKeyListener(new View.OnKeyListener()
      @Override
      public boolean onKey(View v, int keyCode, KeyEvent event)
      if ((keyCode == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
      final String text = textMessage.getText().toString();
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(SEND_MESSAGE);
      connectionThread.out.writeUTF(text);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();
      textMessage.getText().clear();
      return true;

      return false;

      );

      lvRooms.setOnItemClickListener(new AdapterView.OnItemClickListener()
      @Override
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
      final String roomName = roomsAdapter.getItem(i);
      Thread out = new Thread(new Runnable()
      @Override
      public void run()
      try
      connectionThread.out.writeUTF(JOIN_ROOM);
      connectionThread.out.writeUTF(roomName);
      catch (IOException e)
      e.printStackTrace();


      );
      out.start();
      hideRoomScreen();
      showChatScreen();

      );


      public void addMessage(String message)
      adapter.add(message);
      lvMessages.setSelection(adapter.getCount() - 1);


      public void addRoom(final String roomName)
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomsAdapter.add(roomName);

      );


      protected class ConnectionThread extends Thread
      Socket connection;
      DataInputStream in;
      DataOutputStream out;
      String handle;
      boolean connected;

      public ConnectionThread(String name)
      handle = name;


      @Override
      public void run()
      try
      connection = new Socket("10.0.0.10", 1234);
      connected = true;

      in = new DataInputStream(connection.getInputStream());
      out = new DataOutputStream(connection.getOutputStream());

      out.writeUTF(handle);

      hideLoginScreen();
      btnRoom.callOnClick();

      String command = "";
      while (connected)
      command = in.readUTF();
      switch (command)
      case SEND_MESSAGE:
      final String user = in.readUTF();
      final String message = in.readUTF();
      runOnUiThread(new Runnable()
      @Override
      public void run()
      addMessage(user + ": " + message);

      );
      break;
      case DISCONNECT:
      showLoginScreen();
      connected = false;
      break;
      case LIST_ROOMS:
      int count = in.readInt();
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomsAdapter.clear();

      );
      for(int i = 0; i < count; i++)
      String roomName = in.readUTF();
      addRoom(roomName);

      break;



      catch (IOException e)
      e.printStackTrace();





      private void showLoginScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      loginPanel.setVisibility(View.VISIBLE);

      );


      private void hideLoginScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      loginPanel.setVisibility(View.GONE);

      );


      private void showChatScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      chatPanel.setVisibility(View.VISIBLE);

      );


      private void hideChatScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      chatPanel.setVisibility(View.GONE);

      );


      private void showRoomScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomPanel.setVisibility(View.VISIBLE);

      );


      private void hideRoomScreen()
      runOnUiThread(new Runnable()
      @Override
      public void run()
      roomPanel.setVisibility(View.GONE);

      );









      java android multithreading networking






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 13 '18 at 1:56









      Sithe

      1509




      1509






















          1 Answer
          1






          active

          oldest

          votes


















          1














          AsyncTask was not designed to remain active and to receive commands, so I'm not agree with who suggest to use it.
          You need a Thread that remains active for an undetermined amount of time and that receive commands. It's physically possible to use AsyncTask in that similar way but this case is similar to one that uses a Component for a complete different thing, like when using a TextView to display images (by substitute common ImageView and manually draw on TextView): it's possible but....the question is: "WHY?"



          There isn't any advantage by using it.






          share|improve this answer




















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272673%2fis-using-asynctask-in-a-multi-user-chat-android-client-better-than-extending-a-c%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            AsyncTask was not designed to remain active and to receive commands, so I'm not agree with who suggest to use it.
            You need a Thread that remains active for an undetermined amount of time and that receive commands. It's physically possible to use AsyncTask in that similar way but this case is similar to one that uses a Component for a complete different thing, like when using a TextView to display images (by substitute common ImageView and manually draw on TextView): it's possible but....the question is: "WHY?"



            There isn't any advantage by using it.






            share|improve this answer

























              1














              AsyncTask was not designed to remain active and to receive commands, so I'm not agree with who suggest to use it.
              You need a Thread that remains active for an undetermined amount of time and that receive commands. It's physically possible to use AsyncTask in that similar way but this case is similar to one that uses a Component for a complete different thing, like when using a TextView to display images (by substitute common ImageView and manually draw on TextView): it's possible but....the question is: "WHY?"



              There isn't any advantage by using it.






              share|improve this answer























                1












                1








                1






                AsyncTask was not designed to remain active and to receive commands, so I'm not agree with who suggest to use it.
                You need a Thread that remains active for an undetermined amount of time and that receive commands. It's physically possible to use AsyncTask in that similar way but this case is similar to one that uses a Component for a complete different thing, like when using a TextView to display images (by substitute common ImageView and manually draw on TextView): it's possible but....the question is: "WHY?"



                There isn't any advantage by using it.






                share|improve this answer












                AsyncTask was not designed to remain active and to receive commands, so I'm not agree with who suggest to use it.
                You need a Thread that remains active for an undetermined amount of time and that receive commands. It's physically possible to use AsyncTask in that similar way but this case is similar to one that uses a Component for a complete different thing, like when using a TextView to display images (by substitute common ImageView and manually draw on TextView): it's possible but....the question is: "WHY?"



                There isn't any advantage by using it.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 13 '18 at 7:15









                emandt

                911156




                911156



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272673%2fis-using-asynctask-in-a-multi-user-chat-android-client-better-than-extending-a-c%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Top Tejano songwriter Luis Silva dead of heart attack at 64

                    ReactJS Fetched API data displays live - need Data displayed static

                    政党