gpt4 book ai didi

java - 在多用户聊天 Android 客户端中使用 AsyncTask 是否比扩展连接线程更好?

转载 作者:行者123 更新时间:2023-12-02 10:36:17 25 4
gpt4 key购买 nike

我正在使用 Java 服务器和 Android 客户端练习多客户端网络。我之前曾使用 Java 客户端完成过此操作,因此我主要围绕我在 Java 中使用多线程的知识来调整我的解决方案。这是为创建的每个客户端连接扩展一个线程。我通常在 Java 中有一个单独的 ClientConnection 类,但这里我使用了 protected 内部类。

这个解决方案有效,但有人向我提到我可能想使用 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);
}
});
}

}

最佳答案

AsyncTask 的设计目的不是保持 Activity 状态并接收命令,因此我不同意谁建议使用它。您需要一个在不确定的时间内保持 Activity 状态并接收命令的线程。从物理上讲,以类似的方式使用 AsyncTask 是可行的,但这种情况类似于使用 Component 来完成完全不同的事情,例如使用 TextView 来显示图像(通过替换常见的 ImageView 并在 TextView 上手动绘制):这是可能的,但是....问题是:“为什么?”

使用它没有任何优势。

关于java - 在多用户聊天 Android 客户端中使用 AsyncTask 是否比扩展连接线程更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53272673/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com