循环中服务崩溃 - Android Studio

时间:2015-08-31 19:20:45

标签: android

我基本上打算开放一项服务,每隔10秒,就会出现一个祝酒词说“#10; 10秒过去" 这就是我想要做的事情, 经过多次研究,我发现要循环服务我 需要使用while(true) - sleep ...方法...... 但每次启动服务时服务或我的应用程序都会崩溃 (或者每次计时器用完时都准确无误)

我的问题是什么?

我的猜测是,我传递给吐司的传染病可能是错的? 也许还有另一种方法可以在循环中每隔10秒显示一次吐司(在一个服务中)?

这是我的服务代码>

package com.greenroad.candidate.mywallpaperchanger;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

/**
 * Created by pitsponet on 31/08/2015.
 */
public class myService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

@Override
public void onCreate() {
    super.onCreate();

    Toast.makeText(getApplicationContext(), "service created",
            Toast.LENGTH_LONG).show();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    //try to run loop for showing up a toast
    new Thread(new Runnable(){
        public void run() {
            // TODO Auto-generated method stub
            while(true)
            {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //REST OF CODE HERE//
                Toast.makeText(getApplicationContext(), "service started",
                        Toast.LENGTH_LONG).show();
            }

        }
    }).start();


    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
    super.onDestroy();

    Toast.makeText(getApplicationContext(), "service stoped",
            Toast.LENGTH_LONG).show();
}
}

2 个答案:

答案 0 :(得分:1)

服务崩溃的原因是您尝试在主线程之外运行UI任务(Toasts)。由于您正在为无限循环创建辅助线程,因此您需要将Toast调用发布到主循环器,如下所示:

path: FSLASH FSLASH pathContents FSLASH?;
pathContents: (X)+;

话虽如此,我强烈反对在将在设备上运行的任何代码中使用Thread.sleep(),因为这可能会导致一些严重的问题。您应该能够使用Timer来完成相同的事情(并且还可以摆脱无限的while循环)。

要使用Timer,您应该可以执行以下操作:

final Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
mainHandler.post(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getApplicationContext(), "Text to display", Toast.LENGTH_LONG).show();
    }
});

这是一个完整的例子:

// Schedules a TimerTask to execute every 10 seconds after a 10 second delay.
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        // Your Toast code here.
    }
}, 10000, 10000);

答案 1 :(得分:1)

正如Brad所解释的那样,崩溃的原因是因为您尝试从非UI Thread执行UI操作。

要实现您要执行的操作,请在服务中使用以下代码。首先删除Thread

中的onStartCommand()
public class MyService extends Service {
    private Handler mHandler;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mHandler.postDelayed(ToastTask, 10000); // Starts the loop here
        super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        // Stop the loop
        mHandler.removeCallbacks(ToastTask);
        super.onDestroy();
    }
    private Runnable ToastTask = new Runnable() {
        @Override
        public void run() {
            Toast.makeText(MyService.this, "10 Seconds have passed", Toast.LENGTH_SHORT).show();
            // Schedule this Runnable to run again after 10 sec
            mHandler.postDelayed(this, 10000);
        }
    }
}