Service中onStartCommand方法返回值的探索

转载请注明转自:noyet12的博客
博客原址:http://blog.csdn.net/u012975705/article/details/49944313
源码下载地址:
(csdn)http://download.csdn.net/detail/u012975705/9283991

前言

onStartCommand方法的返回值 有4种:START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
下面通过结合demo测试结果来解释每种返回值所代表的意义。

先看测试代码

服务器类

MyService.java

package com.noyet.practice.servicedemo.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * package: com.noyet.practice.servicedemo.service
 * Created by noyet on 2015/11/19.
 */
public class MyService extends Service {

    private final String TAG = "MyService";
    private final int DELAY = 2000;

    private Handler mHander = new Handler();
    private Runnable mTask = new Runnable() {

        @Override
        public void run() {
            Log.d(TAG, DELAY / 1000 + "s after");
            // 故意制造异常,使该进程挂掉
            Integer.parseInt("ok");
        }
    };

    public static void startService(Context context) {
        Intent intent = new Intent(context, MyService.class);
        context.startService(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "   onCreate");
        mHander.postDelayed(mTask, DELAY);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "   onStartCommand    startId = " + startId);
        Log.d(TAG, "   onStartCommand    intent = " + intent);
        /** START_NOT_STICKY | START_STICKY | START_REDELIVER_INTENT | START_STICKY_COMPATIBILITY */
        return START_STICKY_COMPATIBILITY;
    }

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

    @Override
    public void onDestroy() {
        Log.d(TAG, "   onDestroy");
        super.onDestroy();
    }
}

测试类

MainActivity.java

package com.noyet.practice.servicedemo;

import android.app.Activity;
import android.os.Bundle;

import com.noyet.practice.servicedemo.service.MyService;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyService.startService(this);
    }
}

使用START_STICKY作为返回值

测试结果:
这里写图片描述
程序被异常kill后(服务被重启了,但intent对象被清除了)
这里写图片描述

系统在调用完onStartCommand()方法后,如果当前服务被终止了,系统会使该服务保持在启动状态,不过它不会保留之前传递的Intent对象。但是由于它保持启动状态,随后系统会尝试重新创建service,但之前的Intent对象没有被保存。在这个情况下,如果期间没有任何启动命令被传递到Service,那么参数Intent将为null。因此使用START_STICKY作为返回值,适用于不执行命令的媒体播放器(或类似的服务),它只是无限期的运行着并等待工作的到来.

使用START_NOT_STICKY作为返回值

测试结果:
这里写图片描述
程序被异常kill后(服务没有被重建)
这里写图片描述
系统在调用完onStartCommand方法后,如果当前服务被终止了并且在此期间没有任何启动命令被传递到Service,那么系统将是使当前服务退出启动状态,并且除非重新调用Context.startService(Intent),否则不会重新被创建(即不会重新调用onCreate方法)。因为当前服务退出了启动状态,所以除非在此期间启动命令被传递到Service,否则也不会调用。这是最安全的选项,用来避免在不需要的时候运行你的服务。onStartCommand方法。

使用START_REDELIVER_INTENT作为返回值

测试结果:
这里写图片描述
程序被异常kill后(服务被重启了,并保留了intent对象)
这里写图片描述

这里写图片描述

使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。并且在在该服务调用stopSelf方法之前,能够一直保留intent对象数据。这适用于那些应该立即恢复正在执行的工作的服务,如下载文件。

使用START_STICKY_COMPATIBILITY作为返回值

START_STICKY的兼容版本,但不保证服务被终止后一定能重启。
测试结果:
这里写图片描述
程序被异常kill后(服务虽然被重建,但没有重启)
这里写图片描述

发布了45 篇原创文章 · 获赞 84 · 访问量 22万+
展开阅读全文

startservice之后onstartcommand却没有启动

05-28

mainactivity代码 package com.example.test_01; //import android.R; import java.util.List; import com.example.service.PlayerService; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.ImageButton; public class MainActivity extends ActionBarActivity implements MainFragment.OnMainFragmentInteractionListener, MyMusicFragment.OnMyMusicFragmentInteractionListener { //记录当前播放器的状态 private boolean isPause; private FragmentManager fragmentManager; private FragmentTransaction fragmentTransaction; private MainFragment mainFragment; private MyMusicFragment myMusicFragment; //查找歌曲的类 private FindSongs finder; //歌曲列表 public static List<Mp3Info> mp3Infos; //音乐的位置 public static int music_position; //播放按钮控件 private ImageButton play_button; /* 这个方法是activity和fragment通信的一种方法 在MainFragment中调用这个方法,可以在activity中做出相应的反应 */ public void onMainFragmentInteraction(int msg){ /* 对其中的参数msg做出判断,如果为CHANGE_TO_MY_MUSIC_FRAGMENT 则执行跳转 */ if(msg == AppConstant.PlayerMsg.CHANGE_TO_MY_MUSIC_FRAGMENT){ /* 在这里并没有直接切换Fragment 而是调用了activity实现MyMusicFragment的那个接口 对后面的开发能带来一点便利之处 */ onMyMusicFragmentInteraction (AppConstant.PlayerMsg.CHANGE_TO_MY_MUSIC_FRAGMENT); } } public void onMyMusicFragmentInteraction(int msg){ myMusicFragment = new MyMusicFragment(MainActivity.this); //创建了MyMusicFragment的实例 FragmentManager fragmentManager = getFragmentManager(); //得到FragmentManager FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); //得到fragmentTransaction if(msg == AppConstant.PlayerMsg.CHANGE_TO_MY_MUSIC_FRAGMENT){ fragmentTransaction.replace(R.id.fragment_layout, myMusicFragment); fragmentTransaction.addToBackStack(null); //这句话是将被替换的MainFragment加入到一个专门存放fragment的栈中,在回退的时候显示上一个Fragment fragmentTransaction.commit(); } if(msg == AppConstant.PlayerMsg.BACK_TO_MAIN_FRAGMENT){ fragmentTransaction.replace(R.id.fragment_layout, mainFragment); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); } } public void onMyMusicFragmentInteraction(int msg,int position){ if(msg == AppConstant.PlayerMsg.LIST_CLICK){ if (mp3Infos != null) { // Log.i("dada", "-------------here------------"); isPause = false; initService(position); } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); music_position = 0; finder = new FindSongs(); mp3Infos = finder.getMp3Infos(getContentResolver()); play_button = (ImageButton)findViewById(R.id.play_button); //mainFragment = new MainFragment(); //创建了刚才定义的MainFragment实例 mainFragment = new MainFragment(MainActivity.this); fragmentManager = getFragmentManager(); //得到FragmentManager fragmentTransaction = fragmentManager.beginTransaction(); //得到fragmentTransaction,用于管理fragment的切换 fragmentTransaction.replace(R.id.fragment_layout, mainFragment).commit(); //将MainActivity里的布局模块fragment_layout替换为mainFragment } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private void initService(int position) { music_position = position; Mp3Info mp3Info = mp3Infos.get(position); /* 这里新建了一个Intent 里面存放各种即将传给Service的数据 要启动自定义PlayerService类 还需要在AndroidManifest中加入如下代码 <service android:name="com.example.dada.myapplication.PlayerService" android:exported="false" > </service> */ //Intent intent = new Intent("com.example.service.PlayerService"); Intent intent = new Intent(MainActivity.this, PlayerService.class); play_button.setImageResource(R.drawable.play_pause); intent.putExtra("url", mp3Info.getUrl()); intent.putExtra("title", mp3Info.getTitle()); intent.putExtra("artist", mp3Info.getArtist()); intent.putExtra("album", mp3Info.getAlbum()); intent.putExtra("album_id", mp3Info.getAlbum_id()); intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG); intent.setClass(MainActivity.this, PlayerService.class); startService(intent); Log.w("dada", "------------hahaha----------"); } //@Override // public void onFragmentInteraction(int msg) { // // TODO Auto-generated method stub // // } } service代码 package com.example.service; import java.io.IOException; import com.example.test_01.AppConstant; import com.example.test_01.AppConstant.PlayerMsg; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.IBinder; import android.util.Log; public class PlayerService extends Service implements AppConstant { public static MediaPlayer mediaPlayer = null; private int current_position; private String musicPath; private String music_artist; private String music_title; private String notification_msg; //private MediaPlayer mediaPlayer; @Override public IBinder onBind(Intent intent) { Log.w("dada", "-------------here------------"); return null; } /* * onStartCommand()方法就是刚启动service时调用的一个方法 * 里面第一个参数intent就是在activity中的那个intent * 因此里面包含着被点击的歌曲相关信息 */ @Override public int onStartCommand(Intent intent, int flags, int startId) { //MediaPlayer是android中自带的一个播放器类,直接实例化后使用即可 mediaPlayer = new MediaPlayer(); Log.w("dada", "-------------here------------"); try { int msg = intent.getIntExtra("MSG", 0); musicPath = intent.getStringExtra("url"); //从intent中拿出歌曲的路径 Log.w("dada", "-------------here------------"); if (msg == AppConstant.PlayerMsg.PLAY_MSG) { playMusic(0); } } catch (Exception e) { e.printStackTrace(); } return 0; } private void playMusic(int position) { Log.w("dada", "-------------here------------"); try { mediaPlayer.reset(); mediaPlayer.setDataSource(musicPath); mediaPlayer.prepare(); mediaPlayer.setOnPreparedListener(new MyPreparedListener(position)); } catch (IOException e) { e.printStackTrace(); } } private class MyPreparedListener implements MediaPlayer.OnPreparedListener { private int position; public MyPreparedListener(int position) { this.position = position; } public void onPrepared(MediaPlayer mp) { if (position > 0) Log.i("dada", "-------------here------------"); mediaPlayer.seekTo(position); mediaPlayer.start(); } } private void stopMusic() { if (mediaPlayer != null) { mediaPlayer.pause(); } } public void onDestory() { Log.e("dada", "-------------here------------"); if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); } } } startService(intent);后面的log显示了,但是service却没有反应 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览