简体   繁体   English

如何使连接线程保持活动状态? (我需要使用守护程序吗?)

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

My Android application uses a thread to listen for a sockets connection from a PC connected via USB. 我的Android应用程序使用线程侦听来自通过USB连接的PC的套接字连接。 At some point after the PC opens the connection (in response to some user driven event) I want to send some data over it. 在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();
    }
}.

For ages I was scratching my head wondering why I never saw the value of INNER_TAG appear in my logs after touch events. 很久INNER_TAG我一直在想知道为什么我在触摸事件之后为什么从未在日志中看到INNER_TAG的值。 I could use log-debugging to trace the execution into the coordHandler!=null block, but the handler never seemed to fire. 我可以使用日志调试将执行跟踪到coordHandler!=null块中,但是该处理程序似乎从未触发过。

Then it struck me: the thread is probably exiting after completing the connection. 然后让我震惊:完成连接后,线程可能正在退出。 D'uh! '! Not quite sure what I thought was happening before, but I'll blame it on a belief that Loop was doing something magical. 不太确定我之前的想法,但我会认为这是Loop所做的不可思议的事情。

So my question is: How can I keep my thread running? 所以我的问题是:如何保持线程运行? The official Android dev reference on threads briefly mentions that 官方Android开发人员在线程上的参考简要提及

A Thread can also be made a daemon, which makes it run in the background. 也可以将Thread设为守护程序,使其在后台运行。

This naturally made my *nix senses tingle. 这自然使我的* nix感到发麻。 (Incidentally, have you seen the new Spiderman film yet? It's pretty good.) Is daemonisation the answer? (顺便说一句,您看过新的《蜘蛛侠》电影吗?还不错。)守护进程是答案吗? Or have I completely lost the plot? 还是我完全失去了情节?

Use Service in Android. 在Android中使用服务

You can use Service to run at the background.. 您可以使用Service在后台运行。

See this link: 看到这个链接:

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

See this link for the example: 有关示例,请参见此链接:

Example: Communication between Activity and Service using Messaging 示例:使用消息传递在活动和服务之间进行通信

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

  2. Maybe add synchronized blocks when setting/getting handler instance (it is in different threads after all :)) 可能在设置/获取处理程序实例时添加了同步块(毕竟它位于不同的线程中:)

  3. Loop actually does the magic ;) 循环实际上是神奇的;)

  4. In onDestroy quit Looper for serverThread 在onDestroy退出serverThread的Looper

  5. And last but not least (although it does not concern Handler/Looper subject is probably the reason why you never see in logs what you expect): instead of boolean onTouchEvent(MotionEvent event) use boolean dispatchTouchEvent(MotionEvent ev) as onTouchEvent due to docs is Called when a touch screen event was not handled by any of the views under it. 最后但并非最不重要的一点(尽管它不涉及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. so probably this handler method is never called 所以可能永远不会调用此处理程序方法

EDIT: Are you sure it executes sendMessage? 编辑:您确定它执行sendMessage吗? And by the way why do you use Log.v ? 以及为什么您要使用Log.v it assumes you have logging level set to verbose otherwise the logs will be abandoned. 假设您已将日志记录级别设置为详细,否则日志将被放弃。 I suggest to use rather Log.i . 我建议使用宁可使用Log.i

Maybe try this code: 也许尝试下面的代码:

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.

相关问题 如何启动线程但保持一段时间? - How do I start a Thread but keep it alive for a certain time? 如何使用Java使TCP连接保持活动状态? - How can I keep TCP connection alive with Java? 发送 IMAP idle 命令后我是否需要做其他事情以保持连接活跃? - Do I need to do something else after sending IMAP idle command in order to keep the connection alive? 如果守护程序线程正在运行,如何使程序保持活动状态? - How to keep my program alive for as long a daemon thread is running? 如果2个不同的写入和读取线程永远不会同时存在,我是否需要使用volatile - Do I need to use volatile, if 2 different write and read thread will never alive at the same time 我怎么知道什么时候关闭HTTP 1.1 Keep-Alive连接? - How do I know WHEN to close an HTTP 1.1 Keep-Alive Connection? 我应该保持 JDBC 连接处于活动状态吗? - Should I keep JDBC connection alive? 如何在java中将主线程作为守护线程? - How can i make the main Thread as Daemon Thread in java? 如果是解决方案,我如何保持活动的活力 - How can i keep an activity alive, if it's the solution 我如何在Android上保持Jsch Session存活 - How can i keep a Jsch Session alive on android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM