Android - 服务(+补间)

1.进程概念 

   进程代表不同应用程序,系统会为每个应用程序创建一个进程和线程(主线程)
   进程分类 
       1.前台进程  Foreground process   :用户正在交互 ,当广播接收者的onReceive方法执行
       2.可视进程  Visible process   用户不可以交互 但是可以看得见
       3.服务进程  Service process  进程里面运行了一个服务    (音乐播放器)
       4.后台进程  Background process 用户看不见 相当于activity执行了onStop方法
       5.空进程  Empty process  不会立刻杀死 目的是为了 下一次打开速度.

2.服务的入门

    服务是在后台运行.和windos下服务类似 activity你大爷--->Service.
    startservice特点
    1.第一次启动服务 服务会执行onCreate和onStart方法 
    2.当第二次在点击按钮开启服务 服务只会执行onStrat方法 服务一旦开启就会在后台长期运行,直到用户手动停止.

3.电话监听器

    代码实现步骤
    1.开启一个服务 服务在后台监听电话的状态 
 
   
  1. public class PhoneService extends Service {
  2. public PhoneService() {
  3. }
  4. @Override
  5. public IBinder onBind(Intent intent) {
  6. throw new UnsupportedOperationException("Not yet implemented");
  7. }
  8. //当服务第一次创建的时候执行 监听电话的状态
  9. @Override
  10. public void onCreate() {
  11. //1.通过查看文档得知 使用getSystemService方法获取实例
  12. TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
  13. //2.监听电话的状态
  14. tm.listen(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);
  15. super.onCreate();
  16. }
  17. //定义电话监听类 为什么要继承
  18. class MyPhoneStateListener extends PhoneStateListener{
  19. //当设备的状态发生改变的时候执行 state代表电话的状态
  20. @Override
  21. public void onCallStateChanged(int state, String incomingNumber) {
  22. //1.判断电话状态
  23. switch (state){
  24. case TelephonyManager.CALL_STATE_IDLE: //空闲状态
  25. break;
  26. case TelephonyManager.CALL_STATE_OFFHOOK://摘机 接听状态
  27. System.out.println("开始录");
  28. break;
  29. case TelephonyManager.CALL_STATE_RINGING: //响铃状态
  30. System.out.println("准备录音机");
  31. break;
  32. }
  33. super.onCallStateChanged(state, incomingNumber);
  34. }
  35. }
  36. }
   2.具体实现录音功能
 
   
  1. {
  2. //1.判断电话状态
  3. switch (state){
  4. case TelephonyManager.CALL_STATE_IDLE: //空闲状态
  5. if (recorder!=null){
  6. recorder.stop(); //停止录
  7. recorder.reset();
  8. recorder.release();
  9. }
  10. break;
  11. case TelephonyManager.CALL_STATE_OFFHOOK://摘机 接听状态
  12. recorder.start();
  13. System.out.println("开始录");
  14. break;
  15. case TelephonyManager.CALL_STATE_RINGING: //响铃状态
  16. System.out.println("准备录音机");
  17. //1.创建MediaRecorder实例
  18. recorder = new MediaRecorder();
  19. //2.设置音频的来源 mic 麦克风
  20. recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  21. //3.设置输出文件文件 3gp mp4 avi
  22. recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  23. //4.设置音频编码方式
  24. recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  25. //5.指定文件存储路径
  26. recorder.setOutputFile(getFilesDir().getPath()+"/"+"luyin.3gp");
  27. //6.准备录
  28. try {
  29. recorder.prepare();
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. }
  33. break;
  34. }
  35. super.onCallStateChanged(state, incomingNumber);
  36. }
 3.添加对应权限
 
   
  1. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  2. <uses-permission android:name="android.permission.READ_PHONE_STATE">uses-permission>

4.注册特殊广播接收者.

 
   
  1. public class ScreenService extends Service {
  2. private ScreenReceiver screenReceiver;
  3. public ScreenService() {
  4. }
  5. @Override
  6. public IBinder onBind(Intent intent) {
  7. throw new UnsupportedOperationException("Not yet implemented");
  8. }
  9. @Override
  10. public void onCreate() {
  11. //1.获取ScreenReceiver的实例
  12. screenReceiver = new ScreenReceiver();
  13. //2.构造意图过滤器类
  14. IntentFilter intentFilter = new IntentFilter();
  15. //3.添加action
  16. intentFilter.addAction("android.intent.action.SCREEN_OFF");
  17. intentFilter.addAction("android.intent.action.SCREEN_ON");
  18. //4 .动态去注册广播接收者
  19. registerReceiver(screenReceiver,intentFilter);
  20. super.onCreate();
  21. }
  22. @Override
  23. public void onDestroy() {
  24. //当服务销毁的时候取消注册广播接收者
  25. unregisterReceiver(screenReceiver);
  26. super.onDestroy();
  27. }
  28. }

5.bindservice开启服务特点

   bindservice开启服务在后台找不到.相当于开启了一个隐形的服务.更牛一些. 第一次开启服务会执行onCreate方法和onBind方法.
   当activity销毁的时候 服务也会跟着销毁. 天龙八部-->乔峰 虚竹 段誉 不求同生 但求同死.
   为什么要引入bindservice:目的就是为了调用服务里面的方法.
   

6.bindservice调用服务流程:

   1.在服务内部有一个方法需要我们调用  比如办证方法
 
   
  1. public void banZheng(int money){
  2. if (money > 500){
  3. Toast.makeText(this,"我了是领导,把证给你办了",Toast.LENGTH_LONG).show();
  4. }else{
  5. Toast.makeText(this,"这点钱 还想办事",Toast.LENGTH_LONG).show();
  6. }
  7. }
   2.在服务内部 声明一个中间人对象(IBinder实现类)
 
   
  1. //1.在服务内部定义一个中间人对象 小舅子 (实际上就是IBinder类的实现类)
  2. class Mybinder extends Binder{
  3. //2.这个类的内部定义一个方法 调用办证的方法
  4. public void callBanzZheng(int money){
  5. banZheng(money);
  6. }
  7. }
  3.在服务的onBind方法里面把我们定义的中间人对象返回
 
   
  1. //2.在这个方法把我们定义的中间人对象返回
  2. @Override
  3. public IBinder onBind(Intent intent) {
  4. return new Mybinder();
  5. }
 4.在mainActivity里面调用bindService 目的是为了获取我们定义的中间人对象
 
   
  1. public class MainActivity extends AppCompatActivity {
  2. private BanZhengService.Mybinder mybinder; //就是我们定义的中间人对象
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. //1.创建意图
  8. Intent intent = new Intent(this, BanZhengService.class);
  9. //2.创建conn对象
  10. MyConn myConn = new MyConn();
  11. //3.连接服务
  12. bindService(intent,myConn,BIND_AUTO_CREATE);
  13. }
  14. //点击按钮 调用服务的办证方法
  15. public void click(View view) {
  16. mybinder.callBanzZheng(3);
  17. }
  18. //监视服务的状态
  19. class MyConn implements ServiceConnection{
  20. //当连接成功
  21. @Override
  22. public void onServiceConnected(ComponentName name, IBinder service) {
  23. //在这个方法里面获取我们定义的中间人对象实例
  24. mybinder = (BanZhengService.Mybinder) service;
  25. }
  26. @Override
  27. public void onServiceDisconnected(ComponentName name) {
  28. }
  29. }
  30. }

7.使用接口方式调用服务里面的方法

   接口好处:接口可以隐藏代码内部细节,让程序员暴漏自己想暴漏的方法.
   代码实现步骤
    1.定义一个接口 把想暴漏的方法定义在接口里
    2.在获取中间人对象的方式上发生了变化 

8.混合开启服务--->百度音乐盒

 既想保证服务在后台长期运行,又想调用服务里面的方法,使用哪个方式开启服务.
 
   
  1. //混合方式开启服务的流程
  2. //1.为了提升进程优先级 保证服务在后台长期运行
  3. Intent intent = new Intent(this,MusicService.class);
  4. startService(intent);
  5. //2.通过调用bindservice 来获取我们定义的中间人对象
  6. bindService(intent,new Myconn(),BIND_AUTO_CREATE);

9.远程服务和本地服务

   远程服务: 运行在其他应用里面服务
   本地服务: 运作在自己应用的服务

10.aidl

aidl是什么     aidl:android interface definition language android接口定义语言
aidl 有什么用 aidl专门用来解决进程间通信(IPC)
aidl 怎么用   
     实现步骤
    1.直接main目录下创建一个aidl文件 点击同步按钮  让系统帮助我们生成一个iservice.java文件
    2.在iservice.java文件里面系统会自动生成一个stub类 stub类默认继承binder并且实现了iservice接口
    3.把我们定义的中间人对象继承Stub
    4.直接把aidl文件拷贝到另外一个应用程序 点击同步按钮 直接也会生成iservice文件
    5.获取中间人对象的方式不一样了 
 
   
  1. iservice = Iservice.Stub.asInterface(service);
   关于面试的问题: 
          你了解ipc么 如何实现ipc:  aidl
          你用过aidl么,ipc.

11.aidl应用场景

    新浪:微博  通过aidl接口对外暴漏数据  api开发接口. 天气应用:墨迹天气
    支付宝暴漏支付接口 ,斗地主买豆.

12.补间动画 

 
   
  1. //点击按钮实现 透明动画效果
  2. public void click1(View view) {
  3. //创建一个透明动画实例 参数1:代表开始透明值 1.0代表完全不透明 0.0完全透明
  4. AlphaAnimation aa = new AlphaAnimation(1.0f,0.0f);
  5. //设置动画执行时长
  6. aa.setDuration(2000);
  7. //设置动画重复次数
  8. aa.setRepeatCount(1);
  9. //设置动画执行重复的模式
  10. aa.setRepeatMode(Animation.REVERSE);
  11. //让iv执行动画
  12. iv.startAnimation(aa);
  13. }
  14. //点击按钮 实现旋转动画
  15. public void click2(View view){
  16. //参数3和参数4 决定了小机器人X轴旋转的位置:控件真实位置 0.5 代表控件宽*0.5
  17. RotateAnimation ra = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
  18. //设置动画执行时长
  19. ra.setDuration(2000);
  20. //设置动画重复次数
  21. ra.setRepeatCount(1);
  22. //设置动画执行重复的模式
  23. ra.setRepeatMode(Animation.REVERSE);
  24. //让iv执行动画
  25. iv.startAnimation(ra);
  26. }
  27. //点击按钮 实现缩放(放大和缩小)动画
  28. public void click3(View view) {
  29. //参数1 1.0f代表默认值
  30. ScaleAnimation sa = new ScaleAnimation(1.0f,2.0f,1.0f,2.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
  31. //设置动画执行时长
  32. sa.setDuration(2000);
  33. //设置动画重复次数
  34. sa.setRepeatCount(1);
  35. //设置动画执行重复的模式
  36. sa.setRepeatMode(Animation.REVERSE);
  37. //让iv执行动画
  38. iv.startAnimation(sa);
  39. }
  40. //点击按钮实现位移效果
  41. public void click4(View view) {
  42. //想实现位移 不能相对自己 0.2 :代表相对布局高度*0.2 慎用整数
  43. TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT,0.0f,Animation.RELATIVE_TO_PARENT,0.0f,
  44. Animation.RELATIVE_TO_PARENT,0.0f,Animation.RELATIVE_TO_PARENT,0.2f);
  45. //设置动画执行时长
  46. ta.setDuration(2000);
  47. //让动画执行完 停留在介绍的位置上
  48. ta.setFillAfter(true);
  49. //让iv执行动画
  50. iv.startAnimation(ta);
  51. }
总结 补间动画原理: 不会改变控件真实的坐标,只是产生了一个动画效果而已. 



      

    

     
    
  

你可能感兴趣的:(Android - 服务(+补间))