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

我有一个Android应用程序,是一个简单的聊天服务器的客户端。我能够连接到服务器和我的ObjectStreams。问题是当我收到一条消息时,处理我的服务器连接的线程调用显示更新列表视图的消息。Android问题更新ListView动态基于套接字

我收到错误“只有创建视图层次结构的原始线程可以触及其视图。”

我敢肯定它,因为我打电话给我的displayMessage()从我的连接线的方法,但我不知道如何安排我的线程对服务器的连接,并动态更新列表视图我。

这是我的主要活动。

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的代码。您正在后台线程上刷新您的列表视图。

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

}

});

另一种方法是使用asynctask。在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();

}

}

}

}

}

以上是 Android问题更新ListView动态基于套接字 的全部内容, 来源链接: utcz.com/qa/259706.html

回到顶部