Я практикую многопользовательскую сеть, используя Java Server и клиенты Android. Я делал это с клиентами Java раньше, поэтому я адаптировал свое решение в основном к тому, что я знаю в Java, используя многопоточность. Который расширяет поток для каждого созданного клиентского соединения. У меня обычно есть отдельный класс ClientConnection в Java, но здесь я использовал защищенный внутренний класс.
Это решение работает, но кто-то сказал мне, что я мог бы сделать это с AsyncTask. Какие преимущества дает использование AsyncTask вместо расширения потока, как я это сделал здесь?
Пожалуйста, обратите внимание, что я не спрашиваю какой-либо код или как я буду делать это. Каковы преимущества этого метода по сравнению с этим методом?
Макет клиента
<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>
Код клиента
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);
}
});
}
}