2013-01-03 39 views
0

我想通过在android上按按钮发送命令到互联网。Android AsyncTask网络连接

我知道网络部分不应该写在主线程上,所以我使用AsyncTask来完成它。

意外地,当我运行Android模拟器时,它总是在我按下按钮时关闭。

public class DroneMain extends Activity { 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_drone_main); 
    droneNavaSocket=new DroneNavaSocket(); 
    droneNavaSocket.execute(); 
    //////// 
    btnForward=(Button)findViewById(R.id.forwardBtn);   

} 

public Button.OnClickListener btnForwardListener= 
    new Button.OnClickListener(){ 
    @Override 
    public void onClick(View arg0) { 
     action = "Go Forward (pitch+)"; 
     Log.e("///button","forward_enter1"); 
     // at_cmd = "AT*PCMD=" + (seq++) + ",1," + intOfFloat(speed) + ",0,0,0"; 
     at_cmd = "AT*PCMD=" + (seq++) + ",1,0," + intOfFloat(-speed) + ",0,0"; 
     Log.e("///button","forward_enter2"); 
     //  AT*PCMD=1,0,-1110651699,0,0 'forward 
     Log.e("///button","outforward"); 
     try { 
      send_at_cmd(at_cmd); 
      Log.e("///button","forward"); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

}; 

    @Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_drone_main, menu); 

    return true; 
} 
public void send_at_cmd(String at_cmd) throws Exception { 
    String ip = "192.168.1.1"; 
    StringTokenizer st = new StringTokenizer(ip, "."); 
    byte[] ip_bytes = new byte[4]; 
    if (st.countTokens() == 4){ 
      for (int i = 0; i < 4; i++){ 
       ip_bytes[i] = (byte)Integer.parseInt(st.nextToken()); 
      } 
     } 
     else { 
      System.out.println("Incorrect IP address format: " + ip); 
      System.exit(-1); 
     } 
     try { 
     inet_addr = InetAddress.getByAddress(ip_bytes); 
    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    System.out.println("AT command: " + at_cmd);   
    byte[] buffer = (at_cmd + "\r").getBytes(); 
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, inet_addr, PORT); 
    socket.send(packet); 
    Log.e("///send at command","at command topic"); 
    //socket.receive(packet); //AR.Drone does not send back ack message (like "OK") 
    //System.out.println(new String(packet.getData(),0,packet.getLength()));  
    } 
public class DroneNavaSocket extends AsyncTask<String, Integer, Boolean>{ 


     protected void onPreExecute(){ 
     // TODO Auto-generated method stub  
     //handler =new Handler(); 
     //handler.postDelayed(runnable, 0); 
      super.onPreExecute(); 

     try { 
     socket = new DatagramSocket(); 
    } catch (SocketException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }//Use UDP to transfer 
     try { 
     socket.setSoTimeout(3000); 
    } catch (SocketException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }/*Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. */   
     try { 
     send_at_cmd("AT*CONFIG=1,\"control:altitude_max\",\"2000\""); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } //altitude max 2m 


    } 
    @Override 
    protected Boolean doInBackground(String... arg0) 
    { 

     btnForward.setOnClickListener(btnForwardListener); 
     btnBackward.setOnClickListener(BackwardListener); 
     btnLeft.setOnClickListener(btnLeftListener); 
     btnRight.setOnClickListener(btnRightListener); 
     btnUp.setOnClickListener(btnUpListener); 
     btnDown.setOnClickListener(btnDownListener); 
     // btnEmrgency.setOnClickListener(btnEmrgencyListener); 
     btnTakeoff.setOnClickListener(btnTakeoffListener); 
     btnLanding.setOnClickListener(btnLandingListener); 
     Log.e("///","end of on create"); 
     return null; 
    } 


} 

}

01-04 10:35:56.522: I/dalvikvm(149): Jit: resizing JitTable from 4096 to 8192 
01-04 10:35:58.291: W/InputMethodManagerService(149): Window already focused, ignoring       focus gain of: [email protected] attribute=null 
01-04 10:36:03.171: I/ActivityManager(149): START {act=android.intent.action.MAIN cat= [android.intent.category.LAUNCHER] flg=0x10104000 cmp=com.example.dronedivideandroid/.DroneMain u=0} from pid 218 
01-04 10:36:03.271: D/dalvikvm(149): GC_FOR_ALLOC freed 508K, 6% free 11505K/12167K, paused 86ms, total 105ms 
01-04 10:36:03.321: W/WindowManager(149): Failure taking screenshot for (246x410) to layer 21005 
01-04 10:36:03.371: D/dalvikvm(647): Not late-enabling CheckJNI (already on) 
01-04 10:36:03.382: I/Choreographer(218): Skipped 72 frames! The application may be doing too much work on its main thread. 
01-04 10:36:03.391: D/dalvikvm(36): WAIT_FOR_CONCURRENT_GC blocked 0ms 
01-04 10:36:03.411: I/ActivityManager(149): Start proc com.example.dronedivideandroid for activity com.example.dronedivideandroid/.DroneMain: pid=647 uid=10047 gids={3003, 1028} 
01-04 10:36:03.522: D/dalvikvm(36): GC_EXPLICIT freed 38K, 4% free 7964K/8259K, paused 13ms+5ms, total 130ms 
01-04 10:36:03.532: D/dalvikvm(36): WAIT_FOR_CONCURRENT_GC blocked 0ms 
01-04 10:36:03.642: D/dalvikvm(36): GC_EXPLICIT freed <1K, 4% free 7964K/8259K, paused 4ms+14ms, total 115ms 
01-04 10:36:03.652: D/dalvikvm(36): WAIT_FOR_CONCURRENT_GC blocked 0ms 
01-04 10:36:03.761: D/dalvikvm(36): GC_EXPLICIT freed <1K, 4% free 7964K/8259K, paused 4ms+14ms, total 107ms 
01-04 10:36:03.931: I/Choreographer(218): Skipped 124 frames! The application may be doing too much work on its main thread. 
01-04 10:36:04.071: I/Choreographer(218): Skipped 37 frames! The application may be doing too much work on its main thread. 
01-04 10:36:04.291: E/Trace(647): error opening trace file: No such file or directory (2) 
01-04 10:36:04.391: I/ARMAssembler(35): generated scanline__00000077:03010104_00008001_00000000 [ 89 ipp] (110 ins) at [0x4124aa88:0x4124ac40] in 646000 ns 
01-04 10:36:05.061: I/System.out(647): AT command: AT*CONFIG=1,"control:altitude_max","2000" 
01-04 10:36:05.061: W/System.err(647): android.os.NetworkOnMainThreadException 
01-04 10:36:05.071: W/System.err(647): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117) 
01-04 10:36:05.071: W/System.err(647): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:175) 
01-04 10:36:05.071: W/System.err(647): at libcore.io.IoBridge.sendto(IoBridge.java:473) 
01-04 10:36:05.071: W/System.err(647): at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182) 
01-04 10:36:05.081: W/System.err(647): at java.net.DatagramSocket.send(DatagramSocket.java:284) 
01-04 10:36:05.081: W/System.err(647): at com.example.dronedivideandroid.DroneMain.send_at_cmd(DroneMain.java:268) 
01-04 10:36:05.081: W/System.err(647): at com.example.dronedivideandroid.DroneMain$DroneNavaSocket.onPreExecute(DroneMain.java:311) 
01-04 10:36:05.091: W/System.err(647): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586) 
01-04 10:36:05.091: W/System.err(647): at android.os.AsyncTask.execute(AsyncTask.java:534) 
01-04 10:36:05.091: W/System.err(647): at com.example.dronedivideandroid.DroneMain.onCreate(DroneMain.java:40) 
01-04 10:36:05.091: W/System.err(647): at android.app.Activity.performCreate(Activity.java:5008) 
01-04 10:36:05.091: W/System.err(647): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 
01-04 10:36:05.091: W/System.err(647): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 
01-04 10:36:05.101: W/System.err(647): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
01-04 10:36:05.101: W/System.err(647): at android.app.ActivityThread.access$600(ActivityThread.java:130) 
01-04 10:36:05.101: W/System.err(647): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
01-04 10:36:05.101: W/System.err(647): at android.os.Handler.dispatchMessage(Handler.java:99) 
01-04 10:36:05.101: W/System.err(647): at android.os.Looper.loop(Looper.java:137) 
01-04 10:36:05.101: W/System.err(647): at android.app.ActivityThread.main(ActivityThread.java:4745) 
01-04 10:36:05.101: W/System.err(647): at java.lang.reflect.Method.invokeNative(Native Method) 
01-04 10:36:05.111: W/System.err(647): at java.lang.reflect.Method.invoke(Method.java:511) 
01-04 10:36:05.111: W/System.err(647): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
01-04 10:36:05.111: W/System.err(647): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
01-04 10:36:05.111: W/System.err(647): at dalvik.system.NativeStart.main(Native Method) 
01-04 10:36:05.131: E////(647): end of on create 
01-04 10:36:05.311: D/gralloc_goldfish(647): Emulator without GPU emulation detected. 
01-04 10:36:05.412: I/ActivityManager(149): Displayed com.example.dronedivideandroid/.DroneMain: +2s58ms 
01-04 10:36:08.321: E////button(647): forward_enter1 
01-04 10:36:08.321: D/AndroidRuntime(647): Shutting down VM 
01-04 10:36:08.321: W/dalvikvm(647): threadid=1: thread exiting with uncaught exception (group=0x40a13300) 
01-04 10:36:08.352: E/AndroidRuntime(647): FATAL EXCEPTION: main 
01-04 10:36:08.352: E/AndroidRuntime(647): java.lang.NullPointerException 
01-04 10:36:08.352: E/AndroidRuntime(647): at com.example.dronedivideandroid.DroneMain.intOfFloat(DroneMain.java:64) 
01-04 10:36:08.352: E/AndroidRuntime(647): at com.example.dronedivideandroid.DroneMain$1.onClick(DroneMain.java:75) 
01-04 10:36:08.352: E/AndroidRuntime(647): at android.view.View.performClick(View.java:4084) 
+1

发布您的logcat。其他人需要花费更少的时间才能发现问题出在哪里,而不是花太多时间来查看整个代码。 – Kanth

+0

通过asyncObj.execute()调用你的异步任务doInBackground()点击按钮后 –

+0

我刚刚添加我的日志猫 – DekangHu

回答

0

你或许应该设置按钮的点击监听器里onCreate()本身。现在你将它设置在AsyncTask的doInBackground()中。

所以,只要删除该行并添加这里面onCreate()

btnForward=(Button)findViewById(R.id.forwardBtn);  
btnForward.setOnClickListener(btnForwardListener); 
0

这里

@Override 
protected Boolean doInBackground(String... arg0) { 

       btnForward.setOnClickListener(btnForwardListener); //<<<<<here 

     //......your code... 

您试图访问距离的AsyncTask的doInBackground UI元素。无法直接从doInBackground访问或更新UI元素。

如果要执行doInBackground执行之前的一些任务开始,然后把你的代码中onPreExecute()

,如果你想访问UI elemnts后doInBackground完成,则移动当前的UI元素onPostExecute

设置setOnClickListener对于按钮内部的onPreExecute()代替doInBackground

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 
    btnForward.setOnClickListener(btnForwardListener); 
} 
+0

thx 我会稍后尝试:) – DekangHu

+0

我试过但它仍然意外关闭。 – DekangHu

+0

@HuDekang:然后发布新的日志和更新的代码也 –

0

@炸弹人的答案是正确的 - 你应在活动的onCreate,中拨打setOnClickListener,但您还需要做其他事情

你得到一个错误,当您单击按钮,因为onClick会(总是)可以在主线程中执行,所以你不能从那里打电话send_at_cmd。您应该创建另一个AsyncTask子类来完成这项工作,并从onClick开始execute

我猜你试图通过在后台线程中分配onClickListener来防止这种情况,因为可能它的onClick方法也可能在后台运行。但事实并非如此。