2013-01-15 28 views
0

我遇到的這個問題是我的程序只能通過一個AsyncTask通過TCP發送我的字符串。我已經讀過AsyncTask只能運行一次,運行後它應該被處理掉,如果我需要發送另一個命令,我應該創建另一個線程實例並使用新實例發送新命令。但是,無論什麼原因,當我嘗試創建我的AsyncTask的第二個實例時,什麼都不會發生。一些注意事項。我在onPostExecute例程中添加了一條日誌命令,但我從來沒有看到日誌消息。Android編程:通過AsyncTask遇到TCP問題

我在我的Android的清單文件如下:

<uses-permission android:name="android.permission.INTERNET/> 

這是在調用異步任務的主要活動線程的代碼。

public void SendCommand(int DeviceID, String DeviceName, String CommandName) 
{ 
    //Get the IP address and the port in order to communicate with the device 
    DatabaseHelper dbHelper = new DatabaseHelper(MainActivity.this); 
    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    String dbQuery = "SELECT * FROM " + dbHelper.System_Table + ", " + dbHelper.Devices_Table + ", " + 
      dbHelper.Device_Commands_Table + " WHERE " + dbHelper.System_Table + "." + dbHelper.Attribute_Device_ID + 
      " = " + String.valueOf(DeviceID) + " AND " + dbHelper.Devices_Table + "." + dbHelper.Attribute_Device_ID + 
      " = " + String.valueOf(DeviceID) + " AND " + dbHelper.Device_Commands_Table + "." + dbHelper.Attribute_Device_ID + 
      " = " + String.valueOf(DeviceID) + ";"; 
    Cursor c = db.rawQuery(dbQuery, null); 
    String IPAddress = ""; 
    int Port = 0; 
    String DeviceCommand = ""; 
    if (c.getCount() > 0) 
    { 
     int Finished = 0; 
     while (c.moveToNext() && Finished == 0) 
     { 
      int iColumnDeviceName = c.getColumnIndex(dbHelper.Attribute_Device_Name); 
      int iColumnDeviceCommandName = c.getColumnIndex(dbHelper.Attribute_Command_Name); 
      final String CheckDeviceName = c.getString(iColumnDeviceName); 
      final String CheckCommandName = c.getString(iColumnDeviceCommandName); 
      if (DeviceName.equals(CheckDeviceName) && CheckCommandName.equals(CommandName)) 
      { 
       Finished = 1; 
       int iColumnIPAddress = c.getColumnIndex(dbHelper.Attribute_Device_IP); 
       int iColumnPort = c.getColumnIndex(dbHelper.Attribute_Device_Port); 
       int iColumnDeviceCommandString = c.getColumnIndex(dbHelper.Attribute_Command_String); 
       IPAddress = c.getString(iColumnIPAddress); 
       Port = c.getInt(iColumnPort); 
       DeviceCommand = c.getString(iColumnDeviceCommandString); 
       DeviceCommand = DeviceCommand.replace("<CR>", "\r"); 
       Log.d("Device Command To Send", DeviceCommand); 
      } 
     } 
     c.close(); 
     dbHelper.close(); 
     ArrayList<String> passing = new ArrayList<String>(); 
     ArrayList<String> result = new ArrayList<String>(); 
     passing.add(IPAddress); 
     passing.add(String.valueOf(Port)); 
     passing.add(DeviceCommand); 
     SendCommand SC = new SendCommand(); 
     SC.execute(passing, result); 
    } 
} 

這是上面的例程創建實例並執行的單獨類文件。

public class SendCommand extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> 
{ 
    @Override 
    protected void onPreExecute() 
    { 
     //progress bar 
    } 

    @Override 
    protected ArrayList<String> doInBackground(ArrayList<String>... passing) 
    { 
     Log.d("Async Task", "Started to send command."); 
     //Get the connection info and command to send from the caller 
     String Data = passing[0].toString(); 
     int StopAt = Data.indexOf(","); 
     String IPAddress = Data.toString().substring(1, StopAt); 
     Data = Data.replace("[" + IPAddress + ", ", ""); 
     StopAt = Data.indexOf(","); 
     int Port = Integer.parseInt(Data.toString().substring(0, StopAt)); 
     Data = Data.replace(Port + ", ", ""); 
     StopAt = Data.indexOf("]"); 
     String DeviceCommand = Data.toString().substring(0, StopAt); 
     Send_Command(IPAddress, Port, DeviceCommand); 
     return null; 
    } 

    protected void onPostExecute(Long result) 
    { 
     Log.d("Async Task", "Command Sent"); 
    } 

    private void Send_Command(String IPAddress, int Port, String DeviceCommand) 
    { 
     //Setup the connection parameters 
     SocketAddress SA = new InetSocketAddress(IPAddress, Port); 
     int Timeout = 2000; 
     Socket socket = new Socket(); 

     try 
     { 
      //Attempt to connect to the device 
      socket.connect(SA, Timeout); 
      int Count = 0; 
      int Kill = 0; 
      while (socket.isConnected() == false && Kill == 1) 
      { 
       //Waiting for the connection 
       Count = Count + 1; 
       if (Count == Timeout) 
       { 
        Kill = 1; 
        Log.d("Connection Status", "Timed out"); 
       } 
      } 
      if (socket.isConnected() == true) 
      { 
       //send the command 
       BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
       wr.write(DeviceCommand); 
       wr.flush(); 
       Log.d("Sent Device Command", DeviceCommand); 
       //listen for the response 
       BufferedReader rd = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       String Response; 
       while ((Response = rd.readLine()) != null) 
       { 
        Log.d("Received Device Response", Response); 
       } 
       rd.close(); 
      } 
      //close the socket once the response is received 
      socket.close(); 
     } 
     catch (UnknownHostException e) 
     { 
      Log.d("UnknownHostException", "Something bad happened"); 
     } 
     catch (IOException e) 
     { 
      Log.d("IOException", "Something bad happened"); 
     } 
     finally 
     { 
      if (socket != null) 
      { 
       try 
       { 
        socket.close(); 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 

終於這是我的日誌後,試圖通過TCP發送兩個命令。

01-14 23:53:29.773: D/Device Command To Send(31643): PN 
01-14 23:53:29.773: D/Async Task(31643): Started to send command. 
01-14 23:53:30.108: D/Sent Device Command(31643): PN 
01-14 23:53:30.273: D/Received Device Response(31643): R 
01-14 23:53:31.918: D/Device Command To Send(31643): PF 

我可以看到第一次啓動AsyncTask,它發送命令以及接收來自目標設備的響應。但是,我沒有在日誌中看到「Async Task」,「Command Sent」,因此onPostExecute未執行。

對我在做什麼有什麼想法嗎?

回答

1

onPostExecute簽名是錯誤的。

protected void onPostExecute(Long result) 

應該

protected void onPostExecute(ArrayList<String> result) 

這可能是也很好用@Override註解。

在您的Send_CommandAsyncTask中放入一些額外的調試消息可能是掛在那裏的。

+0

哇感謝您的超級快速響應。 我按照建議對onPostExecute進行了調整,但它仍未顯示在日誌文件中或正在運行AsyncTask的新實例。 如果線程不會自己死掉,有沒有辦法殺死它? – Daisy

+0

@Daisy查看更新的答案。 – auselen

+0

謝謝。當我下班回家時,我會添加更多日誌記錄以更詳細地跟蹤異步任務。 – Daisy

1

目前你是不是從AsyncTask重寫onPostExecute因此改變你的onPostExecute簽名:

@Override 
protected void onPostExecute(ArrayList<String> result)//<Change Long 
                 // to ArrayList<String> 
    { 
     Log.d("Async Task", "Command Sent"); 
    }