使用Service播放背景音乐,随机生成大乐透彩票号码

1 概述

Service服务能够在后台长期运行。其他应用程序组件能启动Service,即便用户切换到另一个应用程序,Service还是可以在后台运行。例如,Service可以在后台播放音乐,监控地理位置的变化等。

1.1 Service分类

Service按照启动方式分为两种类型:
(1)Started Service:
startService()后Service处于启动状态。
(2)Bound Service:
bindService()后Service处于绑定状态。
Started Service与Bound Service的区别:

Started Service

Bound Service

调用startService()方法启动

调用bindService()方法绑定

无返回值

有返回值

启动Service的组件与Service之间无关联,即使关闭改组件,Service会一直运行

启动Service的组件与Service绑定在一起,如果关闭该组件,Service就会停止

回调onStartCommand()方法,允许组件启动Service

回调onBind()方法,允许组件绑定Service

注意:可以在配置文件中将Service声明为私有的,从而阻止其他应用程序访问。

1.2 Service生命周期

Service生命周期按照Service分类分为两种:
(1)通过startService()方法启动Service
需要自己调用stopSelf()或其他组件调用stopService()来停止Service。
(2)通过bindService()方法启动Service
客户端通过IBinder接口与Service通信。客户端通过unbindService()方法关闭连接。多个客户端能绑定到同一个Service。
Service的生命周期分类如下:

2 Started Service

应用程序组件(如Activity)能通过调用startService()来启动Service,参数传递Intent。Service使用onStartCommand()方法来接收Intent。
Android有两个类可以继承以创建Service:
(1)Service。
默认使用应用程序主线程来处理业务;不会自动停止。
(2)IntentService。
新建工作线程来处理业务,需要实现onHandleIntent()方法;当IntentService运行结束后会自动停止。

举例,使用Service播放背景音乐:MusicService
https://github.com/hanyuhang-hz/android-demos
MainActivity.java

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 设置全屏显示
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);


        ImageButton btn_play = (ImageButton) findViewById(R.id.btn_play);


        // 启动服务与停止服务,实现播放背景音乐与停止播放背景音乐
        btn_play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (MusicService.isplay == false) {
                    // 启动服务,从而实现播放背景音乐
                    startService(new Intent(MainActivity.this, MusicService.class));
                    ((ImageButton) v).setImageDrawable(getResources().getDrawable(R.drawable.play, null));
                } else {
                    // 停止服务,从而实现停止播放背景音乐
                    stopService(new Intent(MainActivity.this, MusicService.class));
                    ((ImageButton) v).setImageDrawable(getResources().getDrawable(R.drawable.stop, null));
                }
            }
        });
    }


    @Override
    protected void onStart() {
        // 进入界面时,启动背景音乐服务
        startService(new Intent(MainActivity.this, MusicService.class));
        super.onStart();
    }
}

MusicService.java

public class MusicService extends Service {
    public MusicService() {
    }
    static boolean isplay;
    MediaPlayer player;


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }


    @Override
    public void onCreate() {
        // 创建MediaPlayer对像并加载播放的音乐文件
        player = MediaPlayer.create(this, R.raw.music);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (!player.isPlaying()) {
            player.start();
            isplay = player.isPlaying();
        }
        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onDestroy() {
        player.stop();
        isplay = player.isPlaying();
        player.release();
        super.onDestroy();
    }
}

注意:应用程序应该在任务完成后停止Service,以免浪费系统资源。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hyh.musicservice">


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MusicService">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name=".MusicService"
            android:enabled="true"
            android:exported="true">
        </service>
    </application>


</manifest>

android:enabled="true"
用于指定Service能否被实例化。
android:exported="true"
用于指定其他应用程序组件能否调用Service或者与其交互。当值为false时,只有同一个应用程序的组件能启动或绑定到Service。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <ImageButton
        android:id="@+id/btn_play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/play"
        android:background="@color/btn_bg"
        android:layout_marginTop="@dimen/btn_marginTop"
        android:layout_marginLeft="@dimen/btn_marginLeft"
        />


</RelativeLayout>

3 Bound Service

应用程序组件能调用bindService()方法绑定到Service,接口如下:

bindService(Intent service, ServiceConnection conn, int flags)

service:要启动的service
conn:一个ServiceConnection对象,用于监听访问者与Service之间的连接情况
flags:指定绑定时是否自动创建Service
bindService()后,系统调用Service的onBind()方法,返回IBinder对象与Service通信。
注意:只有Activity,Service和ContentProvider能绑定到Service,BroadcastReceiver不能绑定到Service。

举例,模拟大乐透彩票选号:RandomService
https://github.com/hanyuhang-hz/android-demos
MainActivity.java

public class MainActivity extends Activity {
    BinderService binderService;
    // 文本框组件ID
    int[] tvid = {R.id.textView1, R.id.textView2, R.id.textView3, R.id.textView4, R.id.textView5,
            R.id.textView6, R.id.textView7};


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_random = (Button) findViewById(R.id.btn);


        btn_random.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取BinderService类中的随机数数组
                List number = binderService.getRandomNumber();
                for (int i = 0; i < number.size(); i++) {
                    TextView tv = (TextView) findViewById(tvid[i]);
                    String strNumber = number.get(i).toString();
                    tv.setTextColor(Color.GRAY);
                    tv.setText(strNumber);
                }
            }
        });


    }


    @Override
    protected void onStart() {
        // 设置启动Activity时与后台Service进行绑定
        super.onStart();
        Intent intent = new Intent(this, BinderService.class);
        // 绑定指定Service
        bindService(intent, conn, BIND_AUTO_CREATE);
    }


    @Override
    protected void onStop() {
        // 设置关闭Activity时解除与后台Service的绑定
        super.onStop();
        unbindService(conn);
    }


    // 设置与后台Service进行通讯
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 获取后台Service
            binderService = ((BinderService.MyBinder) service).getService();
        }


        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
}

当Service与绑定它的组件连接成功时将回调onServiceConnected()方法;当Service与绑定它的组件断开连接时将回调onServiceDisconnected()方法。

BinderService.java

public class BinderService extends Service {
    public BinderService() {
    }
    // 创建MyBinder内部类并获取服务对象与Service状态
    public class MyBinder extends Binder {
        public BinderService getService() {  //创建获取Service的方法
            return BinderService.this;
        }
    }


    // 返回MyBinder服务对象
    @Override
    public IBinder onBind(Intent intent) {  // 必须实现的绑定方法
        return new MyBinder();
    }


    // 创建获取随机号码的方法
    public List getRandomNumber() {
        List resArr = new ArrayList();
        String strNumber="";
        // 将随机获取的数字转换为字符串添加到ArrayList数组中
        for (int i = 0; i < 7; i++) {
            int number = new Random().nextInt(33) + 1;
            //把生成的随机数格式化为两位的字符串
            if (number<10) {
                strNumber = "0" + String.valueOf(number);
            } else {
                strNumber = String.valueOf(number);
            }
            resArr.add(strNumber);
        }
        return resArr;
    }




    @Override
    public void onDestroy() {  //销毁该Service
        super.onDestroy();
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hyh.randomservice">


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.RandomService">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <service
            android:name=".BinderService"
            android:enabled="true"
            android:exported="true">
        </service>
    </application>


</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/textView1_marginLeft"
        android:layout_marginTop="@dimen/textView_marginTop"
        android:textColor="@color/textColor"
        />


    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/textView2_marginLeft"
        android:layout_marginTop="@dimen/textView_marginTop"
        android:textColor="@color/textColor"
        />


    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/textView3_marginLeft"
        android:layout_marginTop="@dimen/textView_marginTop"
        android:textColor="@color/textColor"
        />


    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/textView4_marginLeft"
        android:layout_marginTop="@dimen/textView_marginTop"
        android:textColor="@color/textColor"
        />


    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/textView5_marginLeft"
        android:layout_marginTop="@dimen/textView_marginTop"
        android:textColor="@color/textColor"
        />


    <TextView
        android:id="@+id/textView6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/textView6_marginLeft"
        android:layout_marginTop="@dimen/textView_marginTop"
        android:textColor="@color/textColor"
        />


    <TextView
        android:id="@+id/textView7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/textView7_marginLeft"
        android:layout_marginTop="@dimen/textView_marginTop"
        android:textColor="@color/textColor"
        />


    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="@dimen/btn_marginTop"
        android:text="随机选号"
        android:background="@color/btn_Color"
        android:textColor="@color/textColor"
        android:layout_marginLeft="@dimen/btn_marginLeft"
        android:layout_marginRight="@dimen/btn_marginRight"
        />


</RelativeLayout>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值