我是Android应用程序开发的新手。我试图开发一个Android服务器客户端聊天
我的第一个项目。这是客户端的代码。当客户按btnJoin
时,
它将连接到服务器并发送一个字符串。我读了很多例子,其中很多都是
看起来像这样。我得到了networkOnMainThreadException
。如何制作asyncTask
以防止
btnJoin = (Button) findViewById(R.id.buttonJoin);
btnJoin.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket("192.168.1.4", 9092);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF("Hello server!");
txtIP.append(dataInputStream.readUTF() + "\n");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
答案 0 :(得分:2)
将您的代码更改为:
btnJoin.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view){
new LongOperation().execute("");
}
}
private class LongOperation extends AsyncTask<String, Void, String> {
Socket socket = null;
String strresult="";
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
@Override
protected String doInBackground(String... params) {
try {
socket = new Socket("192.168.1.4", 9092);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF("Hello server!");
strresult.append(dataInputStream.readUTF() + "\n");
// txtIP.append(dataInputStream.readUTF() + "\n");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return strresult;
}
@Override
protected void onPostExecute(String result) {
TextView txtIP= (TextView) findViewById(R.id.txtIP);
// txtIP.append(result + "\n");
txtIP.setText(result + "\n");
}
@Override
protected void onPreExecute() {
}
}
答案 1 :(得分:1)
像这样使用AsyncTask:
首先将它嵌套在你的类中,它看起来应该类似于:
private class Communicator extends AsyncTask<Void, Void, Boolean> {
String tmp;
String err;
@Override
protected Boolean doInBackground() {
try {
socket = new Socket("192.168.1.4", 9092);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF("Hello server!");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
@Override
protected void onPreExecute() {
}
@Override
protected void onPostExecute(Boolean result) {
txtIP.append(dataInputStream.readUTF() + "\n");
}
}
当你有AsyncTask时,你可以这样开始:
...
@Override
public void onClick(View v) {
Communicator c=new Communicator();
c.execute();
}
....
答案 2 :(得分:0)
尝试在您的应用中实现此代码
private class LongOperation extends AsyncTask<Object, Integer, Object> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Object doInBackground(Object... params) {
//do hard work here
return params;
}
@Override
protected void onProgressUpdate(Integer... values) {
}
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
}
}
答案 3 :(得分:0)
AsyncTask必须是子类才能使用。子类将覆盖至少一个方法(doInBackground(Params ...)),并且通常会覆盖第二个方法(onPostExecute(Result)。)
以下是子类化的示例:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
创建后,任务执行非常简单:
new DownloadFilesTask().execute(url1, url2, url3);
有关详细信息,请参阅以下链接...
http://www.vogella.com/articles/AndroidPerformance/article.html
http://developer.android.com/reference/android/os/AsyncTask.html