有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程java Android服务

我已经建立了一个列表视图。每个ListView项都包含一个ToggleButton, 它启动或停止服务中的线程

只要切换按钮被激活,线程就需要运行。如果活动停止,服务和激活的线程需要继续

//In MainActivity
@Override
public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
Intent intent = new Intent(context,MyService.class);
intent.putExtra("id",listviewPosition);
startService(intent);
}


//MyService
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // Thread(startId) starten
    HandlerThread thread = new HandlerThread(String.valueOf(startId));
    thread.start();
    // Threads looper holen und beim servicehandler benutzen
    serviceHandler = new ServiceHandler(thread.getLooper());
    listServericeHandler.add(serviceHandler);
    //message ausm pool holen
    Message msg = serviceHandler.obtainMessage();
    msg.arg1 = startId;
    serviceHandler.sendMessage(msg);
    return START_STICKY;
}

private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
    super(looper);
    }

@Override
public void handleMessage(Message msg) {
while (continueUntilToggleButtonIsDeactivated) {
Log.d(MainActivity.TAG, "Thread " + tring.valueOf(msg.arg1)
                + " running: " + url.toExternalForm());
synchronized (this) {
        try {
            //do stuff
            wait(1000);
        } catch (Exception e) {
        }
        }
    }
}
}

所以,每次我激活一个切换按钮时,我都试图在OnStartCommand()中启动一个线程

我不知道的是如何停止线程并使其退出while循环


共 (1) 个答案

  1. # 1 楼答案

    您只需要为while循环创建一个要遵守的标志,就可以知道何时停止。例如:

    private final class ServiceHandler extends Handler {
        private volatile boolean _continueRunning = true;
    
        public ServiceHandler(Looper looper) {
            super(looper);
        }
    
        public void stopRunning() {
            _continueRunning = false;
            this.notify(); //Interrupts the wait
        }
    
        @Override
        public void handleMessage(Message msg) {
            while (_continueRunning) { //Watches the variable
                Log.d(MainActivity.TAG, "Thread " + tring.valueOf(msg.arg1)
                                    + " running: " + url.toExternalForm());
    
            synchronized (this) {
                try {
                    //do stuff
                    wait(1000);
                } catch (Exception e) {}
            }
        }
    }
    

    编辑

    您应该在服务的onCreate()方法中创建处理程序。onStartCommand方法会通知您新的消息

    //In your Service Class
    ...
    private ServiceHandler _serviceHandler;
    
    @Override
    public void onCreate() {
        HandlerThread thread = new HandlerThread("ServiceClassName");
        thread.start();
    
        // Threads looper holen und beim servicehandler benutzen
        serviceHandler = new ServiceHandler(thread.getLooper());
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //message ausm pool holen
        Message msg = _serviceHandler.obtainMessage();
        msg.arg1 = startId;
        serviceHandler.sendMessage(msg);
        return START_STICKY;
    }
    
    private class mRunnable implements Runnable {
        private volatile boolean _continueRunning = true;
    
        @Override
        public void run() {
            while (_continueRunning) { //Watches the variable
                synchronized (this) {
                    try {
                        //do stuff
                        wait(1000);
                    } catch (Exception e) {
                        //Purposefully left blank
                    }
                }
            }
        }
    
        public void stopRunning() {
            _continueRunning = false;
            this.notify();
        }
    }
    

    然后将ServiceHandler更改为

    private final class ServiceHandler extends Handler {
        //TODO whatever type of list you need
        private List<mRunnable> _runningThreads = new LinkedList<mRunnable>();
    
        public ServiceHandler(Looper looper) {
            super(looper);
        }
    
        @Override
        public void handleMessage(Message msg) {
            mRunnable runnable = new mRunnable();
            new Thread(runnable).start();
        }
    }