【问题标题】:How to implement asyncTask for a socket connection如何为套接字连接实现 asyncTask
【发布时间】:2013-03-02 20:21:21
【问题描述】:

我看到了一个在线示例,说明如何在 pc 上的 android 应用程序和 java 服务器之间实现套接字连接。该应用程序在模拟器上完美运行(运行 2.3.3),但它在我的安卓智能手机上强制关闭。

经过一些研究,我得出结论,解决方案是实现 asynctask 方法。但是我在知道如何实施它时遇到了问题。我看到了很多解释,但它们对我的情况没有帮助。这是我正在使用的示例代码,我将将此代码用作我开发的任何其他应用程序的参考模板。

我知道这个问题已经被问了很多(很多很多!),但直到现在我还没有设法完成这项工作。 那么任何人都可以帮助我使用以下代码:

package com.exercise.AndroidClient;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class AndroidClient extends Activity {

EditText textOut;
TextView textIn;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     textOut = (EditText)findViewById(R.id.textout);
     Button buttonSend = (Button)findViewById(R.id.send);
     textIn = (TextView)findViewById(R.id.textin);
     buttonSend.setOnClickListener(buttonSendOnClickListener);
 }

 Button.OnClickListener buttonSendOnClickListener
 = new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
 // TODO Auto-generated method stub
 Socket socket = null;
 DataOutputStream dataOutputStream = null;
 DataInputStream dataInputStream = null;

 try {
  socket = new Socket("192.168.1.101", 8888);
  dataOutputStream = new DataOutputStream(socket.getOutputStream());
  dataInputStream = new DataInputStream(socket.getInputStream());
  dataOutputStream.writeUTF(textOut.getText().toString());
  textIn.setText(dataInputStream.readUTF());
 } catch (UnknownHostException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 finally{
  if (socket != null){
   try {
    socket.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

  if (dataOutputStream != null){
   try {
    dataOutputStream.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

  if (dataInputStream != null){
   try {
    dataInputStream.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }
 ;
}};
}

LogCat

03-03 21:35:59.643: E/Trace(3472): error opening trace file: No such file or directory (2)
03-03 21:36:01.073: D/gralloc_goldfish(3472): Emulator without GPU emulation detected.
03-03 21:36:12.045: D/AndroidRuntime(3472): Shutting down VM
03-03 21:36:12.045: W/dalvikvm(3472): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
03-03 21:36:12.103: E/AndroidRuntime(3472): FATAL EXCEPTION: main
03-03 21:36:12.103: E/AndroidRuntime(3472): android.os.NetworkOnMainThreadException
03-03 21:36:12.103: E/AndroidRuntime(3472):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at libcore.io.Streams.readFully(Streams.java:81)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.io.DataInputStream.readShort(DataInputStream.java:169)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:182)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.io.DataInputStream.readUTF(DataInputStream.java:186)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at com.exercise.AndroidClient.AndroidClient$LongOperation.onPostExecute(AndroidClient.java:80)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at com.exercise.AndroidClient.AndroidClient$LongOperation.onPostExecute(AndroidClient.java:1)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at android.os.AsyncTask.finish(AsyncTask.java:631)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at android.os.Looper.loop(Looper.java:137)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at android.app.ActivityThread.main(ActivityThread.java:4745)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.lang.reflect.Method.invokeNative(Native Method)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at java.lang.reflect.Method.invoke(Method.java:511)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-03 21:36:12.103: E/AndroidRuntime(3472):     at dalvik.system.NativeStart.main(Native Method)
03-03 21:36:14.722: I/Process(3472): Sending signal. PID: 3472 SIG: 9

【问题讨论】:

  • 你的问题是什么
  • 使用 Apache Mina 库。这遵循与侦听器的异步方法

标签: android sockets networking android-asynctask


【解决方案1】:

我假设 Activity 具有打开套接字的正确权限。

我猜想运行代码的问题在于您正在 UI 线程上建立互联网连接。强烈建议不要这样做,有时只会导致应用程序停止。

您是正确的,您需要使用您的代码创建一个 AsyncTask 并触发它。有两个地方可以了解这一点:How to execute web request in its own thread?Is there an accepted best-practice on making asynchronous HTTP requests in Android?

【讨论】:

  • 让我检查一下我是否做对了。在 doInBackground 我做我的套接字连接,例如: socket = new Socket("192.168.1.101", 8888); ...在 onPostExecute 我使用 dataOutputStream = new DataOutputStream(socket.getOutputStream());... ?
  • 在 doInBackground 中完成所有工作。然后使用 onPostExecute (a) 执行任何 UI(屏幕)操作,(b) 更新您从查询中更新的任何数据列表,以及 (c) 将任何消息发送到需要了解信息或连接的其他活动或服务已完成。
  • 所以我在 doInBackground 中建立了套接字连接,并在 PostExecute 中发送和接收字符串。但是现在当我按下发送按钮时,字符串被发送,但应用程序强制关闭!
  • 我更新了帖子。现在我将整个过程放在doInBackground中,手机中的字符串被发送到服务器但随后应用程序强制关闭。
  • 我注意到其中一个错误说:只有创建视图层次结构的原始线程才能触及它的视图。所以我注释掉了 textIn.setText(dataInputStream.readUTF());现在是doInBackground。该应用程序现在可以完美运行!但是我应该把我注释掉的命令放在哪里,以便我可以更改文本字段。
【解决方案2】:

正如 Neil 之前所说:您必须在 doInBackgroud 中使用套接字。也接收字符串。

【讨论】:

  • 我试过了,结果是一样的,手机的字符串被发送到电脑服务器,但是在从电脑收到字符串之前应用程序强制关闭。
  • 现在有什么异常?
  • 你还有那个 NetworkOnMainThreadExeption 吗?如果是这样,则并非所有网络代码都在 DoOnBackground 中。或者你用 .get() 而不是只用 .execute() 实例化你的异步任务。
【解决方案3】:

@nick28:你在第 45 行有一个未捕获的异常,你的第 45 行是什么? 在初始化控件之前尝试以下代码,希望您的应用程序不会关闭:

if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}

【讨论】:

    猜你喜欢
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 2020-06-30
    相关资源
    最近更新 更多