gpt4 book ai didi

java - Android 问题基于套接字动态更新 ListView

转载 作者:行者123 更新时间:2023-11-30 03:34:35 24 4
gpt4 key购买 nike

我有一个 android 应用程序,它是一个简单聊天服务器的客户端。我能够连接到服务器和我的 ObjectStreams。问题是当我收到一条消息时,处理我的服务器连接的线程会根据我更新 ListView 的显示消息调用。

我收到错误“只有创建 View 层次结构的原始线程才能触及它的 View 。”

我很确定这是因为我正在从我的连接线程调用我的 displayMessage() 方法,但我不确定如何组织我的线程以连接到服务器并动态更新我的 ListView 。

这是我的主要 Activity 。

public class MainActivity extends Activity {

private Connection serverConnection;
private ArrayList<String> listItems = new ArrayList<String>();
private ArrayAdapter<String> adapter;
/**
* Sets the ArrayAdaptor, and starts the connectThread.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

runOnUiThread(new Runnable() {
public void run() {
ListView listview = (ListView) findViewById(R.id.list);
adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1,
listItems);
listview.setAdapter(adapter);
}
});
/**
* Starts a new connection Thread
*/
Thread connectThread = new Thread(new Runnable(){
public void run(){
serverConnection = new Connection(MainActivity.this);
serverConnection.run();
}
});
connectThread.start();
}
/**
* Adds a message to the list view.
* @param string - message to be added.
*/
public void displayMessage(String string) {
listItems.add(string);
adapter.notifyDataSetChanged();
}
}

这是我的连接线程类。

public class Connection extends Thread {

private Socket client;
private ObjectOutputStream output;
private ObjectInputStream input;
private MainActivity mainActivity;
private String message;
/**
* Constructor starts the socket and ObjectStreams
*
* @param mainActivity - reference to the MainActivity
*/
public Connection(MainActivity mainActivity) {
this.mainActivity = mainActivity;
try {
client = new Socket("192.168.1.105", 50499);
mainActivity.displayMessage("Connected to: "
+ client.getInetAddress().getHostName());
output = new ObjectOutputStream(client.getOutputStream());
output.flush();
input = new ObjectInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}

}
/**
* Run method for the Thread.
*/
public void run() {
for (;;) {
try {
message = (String) input.readObject();
mainActivity.displayMessage(message);
} catch (OptionalDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

最佳答案

您正在后台线程上更新 Ui。您应该在 ui 线程上更新 ui。移动在后台线程中更新 ui 的代码。您正在后台线程上刷新 ListView 。

 mainActivity.displayMessage("Connected to: "
+ client.getInetAddress().getHostName());
mainActivity.displayMessage(message);

public void displayMessage(String string) {
listItems.add(string);
adapter.notifyDataSetChanged();
}

上面应该在线程外或者你可以在线程内使用runonuithread来更新ui。

      runOnUiThread(new Runnable() {
@Override
public void run() {
// update ui
}
});

另一种方法是使用异步任务。在 doInbackground() 中执行所有与网络相关的操作,并在 onPostExecute() 中更新 ui。

Async Task

编辑:不确定您要做什么。

 public class MainActivity extends Activity {

private Connection serverConnection;
private ArrayList<String> listItems = new ArrayList<String>();
private ArrayAdapter<String> adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listview = (ListView) findViewById(R.id.lv);
adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1,
listItems);
listview.setAdapter(adapter);
// use a button and on button click start the thread.

Thread connectThread = new Thread(new Runnable(){
public void run(){
serverConnection = new Connection(MainActivity.this);
serverConnection.run();
}
});
connectThread.start();
}

public void displayMessage(String string) {
listItems.add(string);
adapter.notifyDataSetChanged();
}
class Connection extends Thread {

private Socket client;
private ObjectOutputStream output;
private ObjectInputStream input;
private MainActivity mainActivity;
private String message;

public Connection(MainActivity mainActivity) {
this.mainActivity = mainActivity;
try {
client = new Socket("192.168.1.105", 50499);
runOnUiThread(new Runnable() {
@Override
public void run() {
displayMessage("Connected to: "
);
}
});

output = new ObjectOutputStream(client.getOutputStream());
output.flush();
input = new ObjectInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}

public void run() {
for (;;) {
try {
message = (String) input.readObject();
runOnUiThread(new Runnable() {
@Override
public void run() {
displayMessage(message);
}
});



} catch (OptionalDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

关于java - Android 问题基于套接字动态更新 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16818984/

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