簡體   English   中英

如何使連接線程保持活動狀態? (我需要使用守護程序嗎?)

[英]How can I keep a connection thread alive? (Do I need to use a daemon?)

我的Android應用程序使用線程偵聽來自通過USB連接的PC的套接字連接。 在PC打開連接后的某個時刻(響應某些用戶驅動的事件),我想通過它發送一些數據。

public void onCreate(Bundle savedInstanceState) {

    // SNIP: stuff and nonsense

    connection = new Thread(new ServerThread());
    connection.start();
}

public boolean onTouchEvent(MotionEvent event) {

    // SNIP: decide what to do; create string 'coordString'

    Message coordMsg = coordHandler.obtainMessage();
    Bundle coordMsgData = new Bundle();
    coordMsgData.putString("coords", coordString);
    coordMsg.setData(coordMsgData);
    if(coordHandler!=null)
    {
        coordHandler.sendMessage(coordMsg);
    }

    return false;
}

public class ServerThread extends Thread
{   
    public void run() {

        this.setName("serverThread");

        Looper.prepare();

        coordHandler = new Handler()
        {
            @Override
            public void handleMessage(Message msg) {
                Log.v(INNER_TAG,"here");
            }
        };

        // SNIP: Connection logic here

        Looper.loop();
    }
}.

很久INNER_TAG我一直在想知道為什么我在觸摸事件之后為什么從未在日志中看到INNER_TAG的值。 我可以使用日志調試將執行跟蹤到coordHandler!=null塊中,但是該處理程序似乎從未觸發過。

然后讓我震驚:完成連接后,線程可能正在退出。 '! 不太確定我之前的想法,但我會認為這是Loop所做的不可思議的事情。

所以我的問題是:如何保持線程運行? 官方Android開發人員在線程上的參考簡要提及

也可以將Thread設為守護程序,使其在后台運行。

這自然使我的* nix感到發麻。 (順便說一句,您看過新的《蜘蛛俠》電影嗎?還不錯。)守護進程是答案嗎? 還是我完全失去了情節?

在Android中使用服務

您可以使用Service在后台運行。

看到這個鏈接:

http://developer.android.com/reference/android/app/Service.html

有關示例,請參見此鏈接:

示例:使用消息傳遞在活動和服務之間進行通信

  1. 更改connection = new Thread(new ServerThread()); 到: connection = new ServerThread();

  2. 可能在設置/獲取處理程序實例時添加了同步塊(畢竟它位於不同的線程中:)

  3. 循環實際上是神奇的;)

  4. 在onDestroy退出serverThread的Looper

  5. 最后但並非最不重要的一點(盡管它不涉及Handler / Looper主題,這可能是您從未在日志中看到期望的原因的原因):由於文檔的緣故,請使用boolean dispatchTouchEvent(MotionEvent ev) MotionEvent boolean dispatchTouchEvent(MotionEvent ev)代替boolean onTouchEvent(MotionEvent event) boolean dispatchTouchEvent(MotionEvent ev)作為onTouchEvent Called when a touch screen event was not handled by any of the views under it. 所以可能永遠不會調用此處理程序方法

編輯:您確定它執行sendMessage嗎? 以及為什么您要使用Log.v 假設您已將日志記錄級別設置為詳細,否則日志將被放棄。 我建議使用寧可使用Log.i

也許嘗試下面的代碼:

ServerThread connection;
Handler coordHandler;

public void onCreate(Bundle savedInstanceState) {
    connection = new ServerThread();
    connection.start();
}

@Override
protected void onDestroy() {
    synchronized (this) {
        if(coordHandler != null) {
            coordHandler.getLooper().quit();
        }
    }
    super.onDestroy();
}

public boolean dispatchTouchEvent(MotionEvent event) {

    synchronized (this) {
        if(coordHandler == null) {
            Log.i(INNER_TAG, "Handler is null");
        }
        else {
            Log.i(INNER_TAG, "Handler exists");
            coordHandler.sendMessage(
                    coordHandler.obtainMessage(
                            0, event.toString()));
        }
    }

    return false;
}

synchronized void setCoordHandler(Handler handler) {
    coordHandler = handler;
}

public class ServerThread extends Thread {

    public void run() {

        this.setName("serverThread");

        Looper.prepare();

        setCoordHandler(new Handler() {

            @Override
            public void handleMessage(Message msg) {
                Log.i(INNER_TAG, "Inside handler");
            }
        });

        Looper.loop();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM