简体   繁体   中英

Threads in Background Service Android

Hi I am trying to use the service class for first time and have been facing problems. What I want is an infinitely running (unless killed by Android System) service with an active Network connection. I have written the code which works fine on Android 4.3 and 4.4 but the application crashes when I try running on Android 2.2. My code is as follows:

public class BackgroundMusicService extends Service {

private MediaPlayer mp;
private int id;

private static class BackgroundAsyncTaskClass extends AsyncTask<Void, Void, Void>{
    protected Void doInBackground(Void... params) {
        Log.v("Async","Async Called");

                    /*Network connection will be created here*/

        return null;
    }
}

private class ForThread implements Runnable{
    public void run() {
        while (true) {
            try {
                Log.v("ThreadSleeping","5 sec");
                BackgroundAsyncTaskClass task = new BackgroundAsyncTaskClass();
                task.execute();
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }finally{
                Log.v("Finally called","Finally called");
            }   
        }
    }
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

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

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.v("onStartCommand Called","onStart Command Called");

    Thread t;
    ForThread ft = new ForThread();
    t = new Thread(ft);
    t.start();

    return START_NOT_STICKY;
}


@Override
public void onDestroy() {
    super.onDestroy();
    if(null != mp){
        mp.stop();
        mp.release();
        Log.v("Destroyed","onDestroy Called");
    }
}

public void onTaskRemoved(Intent rootIntent) {

    Intent restartServiceIntent = new Intent(getApplicationContext(),
            this.getClass());
    restartServiceIntent.setPackage(getPackageName());

    PendingIntent restartServicePendingIntent = PendingIntent.getService(
            getApplicationContext(), 1, restartServiceIntent,
            PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager) getApplicationContext()
            .getSystemService(Context.ALARM_SERVICE);
    alarmService.set(AlarmManager.ELAPSED_REALTIME,
            SystemClock.elapsedRealtime() + 1000,
            restartServicePendingIntent);

    super.onTaskRemoved(rootIntent);
}

}

and the exception thrown by Android 2.2 is as follows:

04-28 09:51:41.435: W/dalvikvm(280): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
04-28 09:51:41.435: E/AndroidRuntime(280): FATAL EXCEPTION: Thread-8
04-28 09:51:41.435: E/AndroidRuntime(280): java.lang.ExceptionInInitializerError
04-28 09:51:41.435: E/AndroidRuntime(280):  at com.example.backgroundservicedemo.BackgroundMusicService$ForThread.run(BackgroundMusicService.java:45)
04-28 09:51:41.435: E/AndroidRuntime(280):  at java.lang.Thread.run(Thread.java:1096)
04-28 09:51:41.435: E/AndroidRuntime(280): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-28 09:51:41.435: E/AndroidRuntime(280):  at android.os.Handler.<init>(Handler.java:121)
04-28 09:51:41.435: E/AndroidRuntime(280):  at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
04-28 09:51:41.435: E/AndroidRuntime(280):  at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
04-28 09:51:41.435: E/AndroidRuntime(280):  at android.os.AsyncTask.<clinit>(AsyncTask.java:152)

Also, when I try using handler.post(new Runnable(){.... run(){}....} The UI hangs up but the background thread continues running and exits after it becomes out of memory.

Another thing that I have doubts about is: When the application restarts, I want this active Service to stop, but how do I get a reference to this thread running in Background and how do I stop this? I would appreciate if anyone can redirect me to a suitable link/reference or could help me out with the code. Thanks

You have this inside a thread's run method

 BackgroundAsyncTaskClass task = new BackgroundAsyncTaskClass();
 task.execute();

Threading rules from the docs

  1. The AsyncTask class must be loaded on the UI thread . This is done automatically as of JELLY_BEAN.

  2. The task instance must be created on the UI thread. execute(Params...) must be invoked on the UI thread.

  3. Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.

  4. The task can be executed only once (an exception will be thrown if a second execution is attempted.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM