0

私は、AndroidアプリとPC上のJavaサーバー間のソケット接続を組み込む方法のオンライン例を見ました。アプリはエミュレーター(2.3.3を実行)で完全に実行されますが、Androidスマートフォンでは強制的に閉じます。

いくつかの調査の結果、解決策は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
4

3 に答える 3

1

アクティビティにはソケットを開くための適切な権限があると想定しています。

コードを実行する際の問題は、UI スレッドでインターネット接続を確立していることだと思います。これは非常に推奨されておらず、アプリケーションが停止するだけの場合もあります。

コードで AsyncTask を作成してトリガーする必要があることは正しいです。これについて学ぶべき 2 つの場所があります:独自のスレッドで Web 要求を実行する方法は? Android で非同期 HTTP リクエストを作成する際に受け入れられているベスト プラクティスはありますか?

于 2013-03-02T20:27:52.620 に答える
0

@ nick28:45行目にキャッチされない例外があります。45行目は何ですか?コントロールを初期化する前に、次のコードを試してください。アプリケーションが閉じないことを願っています。

if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
于 2013-03-03T21:23:29.123 に答える
0

ニールが前に言ったように:あなたはdoInBackgroudのソケットですべてをしなければなりません。文字列も受け取ります。

于 2013-03-03T19:35:25.080 に答える