1
我有一個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();
}
}
}
}
我對你告訴我要移動的位置和內容有些困惑。我的MainActivity中的displayMessage()在runOnUiThread之外。我會研究異步任務,只是想了解我的線程是如何在這裏工作的。 – Collin
@Collin在你的displayMessage方法中,你正在刷新listview。並且你的顯示方法從線程被調用。所以請使用runOnUiThread在ui線程上更新ui或使用asyntask。檢查鏈接中提供的鏈接 – Raghunandan
如何將消息從連接線程傳遞到runOnUiThread?我無法在Connection類中創建runOnUiThread。 – Collin