我遇到的這個問題是我的程序只能通過一個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未執行。
對我在做什麼有什麼想法嗎?
哇感謝您的超級快速響應。 我按照建議對onPostExecute進行了調整,但它仍未顯示在日誌文件中或正在運行AsyncTask的新實例。 如果線程不會自己死掉,有沒有辦法殺死它? – Daisy
@Daisy查看更新的答案。 – auselen
謝謝。當我下班回家時,我會添加更多日誌記錄以更詳細地跟蹤異步任務。 – Daisy