精华内容
下载资源
问答
  • 网上关于保证Service在后台持续运行的方法有很多,但有些其实作用并不大,仅适合原生系统 实际Service的运行,不完全是由代码控制的,很大程度上取...在系统设置-启动管理里面,允许应用后台运行运行应用自启动 ...

    网上关于Service保活和进程保活的文章有很多,但其实大多作用并不大
    这些文章大多是只适合很久以前的旧系统,或者是原生的安卓系统,更多的是以讹传讹,未经实践,实际并不可用

    实际Service的运行,不完全是由代码控制的,很大程度上取决于操作系统的进程管理策略,手机系统、手机性能息息相关

    这里根据我的经验总结出的一些可行的方案,在中高端机型上,基本都能保证Service在后台运行

    锁定后台应用

    这个功能允许应用在后台运行,不被清理,可以点击任务键,再点击带锁图标的菜单开启

    这个不是安卓系统原生的功能,不同的操作系统有不同的打开方法,一般都要点击任务键

    在这里插入图片描述

    在系统设置-启动管理里面,允许应用后台运行

    这个设置允许应用进程在切换到后台时继续运行,但是每个手机的设置方法都有所不同

    这里以华为手机为例,有的手机上叫应用启动管理,有的叫后台运行管理,有的叫电池优化

    安卓系统定制版本太多了,大家需要自己动手多研究下,把系统设置里面权限应用电池相关的选项都过一遍就能找到

    在这里插入图片描述
    允许应用后台获取位置信息

    这对于有定位功能的应用来说很重要,即便应用进程存活,系统也可能限制定位来达到省电目的
    安卓从10.0开始,增加了一个后台定位权限管理功能(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
    需要在Manifest清单中配置此权限,并通过代码动态申请此权限,否则息屏后就会立刻停止定位

    在这里插入图片描述
    关闭电源优化功能

    系统对后台进程和定位进行限制,无非为了两个目的,一个是节省CPU和内存,另一个是续航
    随着手机性能越来越好,很多高端手机已经不存在性能问题,但是电量消耗问题仍然是存在的

    尤其对于定位,视频,屏幕亮度这些功能,大家如果有留意就会知道,它们会明显地大幅提示电量消耗速度
    对于有电源优化设置的手机,大家一定要关闭电源优化
    也有一些比较简单的系统,会把后台运行等设置都归到电源优化功能里面来

    在这里插入图片描述

    将服务设置为前台服务

    这个功能将后台服务转为前台服务,从而避免被系统清理,这个功能对服务保活效果显著,同样也能提升整个进程的存活率
    但相应地,必须将服务与一个前台通知绑定,服务存活期间通知会一直显示,以便告之用户后台应用在运行

    
    	service.startForeground(id, notification);
    
    

    监听系统广播重新启动

    我们可以通过静态注册一个广播接收器,去监听一些比较广播频次比较高系统广播,比如电量更新广播
    当系统发出这些广播时,广播接收器就会被唤起,然后我们在Receiver里面重新启动Service即可

    不过可惜,从安卓8.0开始,静态广播已经受到了严格限制,这个方法现在已经行不通了
    如果所有应用都按这种方法做,系统只要一发广播,就会启动一批应用,非常消耗性能和电量
    所以从安卓8.0开始,发送静态广播必须指定包名和接收器的类名,只有特定应用可以收到,而不再是群发
    我之所以还把它写出来,是因为它代表了一种通用的解决思路,这个思路在其它操作系统中也许是可行的

    多进程守护

    即开启两个或更多个进程,彼此之间定时相互启动,除非两个进程同时被杀,否则就可以达到一直存活的目的

    不过很遗憾,安卓系统从6.0之后,在杀死进程时,会按照包名,将同一个应用下的所有子进程同时杀死
    所以这个方法对于进程复活来说,效果并不理想,但是对于复活Service来说,还是可行的

    
    	//定义一个保活服务基类,服务之间定时相互启动
    	//当服务被启动时,服务所在的进程,自然也随之被唤起
    	public class KeepAliveService extends Service {
    	
    	    public Class<? extends Service>[] services() {
    	        return new Class[]{SA.class, SB.class};
    	    }
    	
    	    @Override
    	    public void onCreate() {
    	        super.onCreate();
    	        WorkThread.postByLoop(() -> {
    	            for (Class<? extends Service> service : services())
    	                startService(new Intent(this, service));
    	            Threads.sleep(5000);
    	        });
    	        Notification notification = Notifications.buildForegroundNotification("应用正在后台运行");
    	        startForeground(Codes.CODE_BACKGROUND_RUNNING, notification);
    	    }
    	
    	    @Override
    	    public int onStartCommand(Intent intent, int flags, int startId) {
    	        Console.info(getClass().getSimpleName(), Applications.currentProcessName(), Applications.currentProcessId(), hashCode());
    	        return Service.START_STICKY;
    	    }
    	
    	    @Nullable
    	    @Override
    	    public IBinder onBind(Intent intent) {
    	        return null;
    	    }
    	}
    
    
    
    	public class SA extends KeepAliveService {
    	
    	    @Override
    	    public int onStartCommand(Intent intent, int flags, int startId) {
    	        Console.info("SA execute its work");
    	        return super.onStartCommand(intent, flags, startId);
    	    }
    	}
    
    
    
    	public class SB extends KeepAliveService {
    	
    	    @Override
    	    public int onStartCommand(Intent intent, int flags, int startId) {
    	        Console.info("SB execute its work");
    	        return super.onStartCommand(intent, flags, startId);
    	    }
    	}
    
    
    
    	<service
    	    android:name=".SA"
    	    android:exported="true"
    	    android:process=":aaa" />
    	
    	<service
    	    android:name=".SB"
    	    android:exported="true"
    	    android:process=":bbb" />
    
    
    
    	//在主进程启动所有服务
    	startService(new Intent(this, SA.class));
    	startService(new Intent(this, SB.class));
    
    

    通过JobScheduler拉活进程

    JobScheduler用于在系统中注册一个定时任务,可以定时启动一个JobService
    所以只要我们的服务继承JobService,就可以定时被JobScheduler唤起

    当然,和其它的功能一样,安卓系统肯定是不可能允许应用通过JobScheduler来作弊,在后台一直运行的
    实际上,JobScheduler最快也得15分钟才能唤醒一次任务,JobService最多只能工作10分钟就会被杀死
    JobScheduler设计出来并不是让用户肆意滥用的,而是给那些需要定时工作,但是工作频次小,工作时间短的功能设计的

    虽然JobScheduler不能保证进程一直存活,但却可以起到定时拉活进程的目的,我们再配合其它技术一起使用,就可以达到一个比较好的效果
    毕竟,服务和进程并不会一启动就会被系统杀死,我们将进程拉活和进程守护功能结合起来,就可以保证进程在大多时间都在工作

    
    	//在触发JobScheduler任务时,启动指定Service来拉活进程
    	public class SJ extends JobService {
    	
    	    public Class<? extends Service>[] services() {
    	        return new Class[]{SA.class, SB.class};
    	    }
    	
    	    @Override
    	    public boolean onStartJob(JobParameters params) {
    	        for (Class<? extends Service> service : services())
    	            startService(new Intent(this, service));
    	        return false;
    	    }
    	
    	    @Override
    	    public boolean onStopJob(JobParameters params) {
    	        return true;
    	    }
    	}
    
    
    
    	//在主进程启动所有服务
    	startService(new Intent(this, SA.class));
    	startService(new Intent(this, SB.class));
    	
    	//启动JobScheduler任务来定时拉活Service进程
    	startKeepAliveJob(1001, SJ.class);
    	
    	//开启一个用于拉活的JobScheduler任务
    	public void startKeepAliveJob(int jobId, Class<? extends JobService> service) {
    		ComponentName componentName = new ComponentName(getPackageName(), service.getName());
    		JobInfo.Builder builder = new JobInfo.Builder(jobId, componentName);
    		builder.setPeriodic(15 * 60 * 1000);
    		builder.setPersisted(true);
    		JobInfo jobInfo = builder.build();
    		JobScheduler scheduler = getSystemService(JobScheduler.class);
    		scheduler.schedule(jobInfo);
    	}
    
    
    
    	<service
    	    android:name=".SA"
    	    android:exported="true"
    	    android:process=":aaa" />
    	
    	<service
    	    android:name=".SB"
    	    android:exported="true"
    	    android:process=":bbb" />
    	
    	<service
    	    android:name=".SJ"
    	    android:exported="true"
    	    android:permission="android.permission.BIND_JOB_SERVICE"
    	    android:process=":job" />
    
    

    设置服务以粘性模式启动

    STICKY模式的服务,会在进程意外中断时,自动重新启动

    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return START_STICKY;
        }
    
    

    综合各种方法技巧

    进程保活并不是一个100%稳定的技术,但是以上的措施都会起到一些作用,有的作用其实非常明显
    将它们结合起来,基本可以保证应用在后台常驻,千万不要偷懒,奢望只用一个方法就能达到目的

    展开全文
  • Android全局异常捕获,不退出应用让应用正常运行下去! 当App发现异常后,如果程序没有处理,将交给虚拟机进行处理,通常会弹出一个对话框,然后退出应用。但大多数的应用可能对后续流程影 响不大,比如分享功能...
     

    不好意思都忘记了还有这么一个博客,我在另外一个博客对这个知识点进行了补充,大家过去可以看看

    https://blog.csdn.net/long8313002/article/details/108422991

     


     

    Android全局异常捕获,不退出应用,让应用正常运行下去!


    当App发现异常后,如果程序没有处理,将交给虚拟机进行处理,通常会弹出一个对话框,然后退出应用。但大多数的异常可能对后续流程影响不大,比如分享功能出现。
    一个问题,真的有必要关闭整个应用吗?屏蔽这个功能,对整体来说不会有太大的影响。或者某个页面的数据出现了逻辑错误,大多数关闭当 前页面, 用户再重新启动
    便可以正常使用了。


    原理介绍:Looper机制是整个App一直运行下去的关键,就和操作系统一样,通过死循环来实现不退出。在Android App 中ActivityThread
    的main方法会主动为主线程创建一个Looper,内部维护一个消息队列MessageQueue,通过循环获取消息,处理消息,来使得App运行下去。比
    如当屏幕被点击,触摸事件通过binder子线程,发送消息给主线程消息队列MessageQueue,主线程得到消息处理。
    发生错误后会发生什么事情呢?循环会停止,将不再处理消息。所以大多数捕获到异常后,界面将会卡死,发生ANR。幸运的是,我们可以在循
    被系统停止前,捕获到它的异常。
     

     new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Looper.loop();
                        } catch (Throwable e) {
                            IHandlerException handler = mainThreadFactory.get(e);
                            if (onExceptionCallBack != null) {
                                onExceptionCallBack.onThrowException(Thread.currentThread(), e, handler);
                            }
                            if (handler == null) {
                                defaultUncaughtExceptionHandler.uncaughtException(Thread.currentThread(), e);
                                return;
                            }
                            if (handler.handler(e)) {
                                return;
                            }
                        }
                    }
                }
            });

     

     

     


    插入一条消息,在循环队列后,这样队列消息的处理,将由我们来完成,当然我们也可以捕获到它发出的异常。说到这里,也许大家会发现,这样似乎只能 捕获主线程的异常
    ,我们仅仅是循环的主线程的消息队列。不过对于子线程来说,默认情况下是没有消息队列的,当然如果你愿意也可以创建,当子线程发生 异常消息循环将会被终止,并且会
    交给RuntimeInit.UncaughtHandler处理。在这之前我们要替换掉它,由自己来处理。

     

     

     

     

     

     

     

     

    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread t, Throwable e) {
                    IHandlerException handler = childThreadFactory.get(e);
                    if (onExceptionCallBack != null) {
                        onExceptionCallBack.onThrowException(t, e, handler);
                    }
                    if (handler == null) {
                        defaultUncaughtExceptionHandler.uncaughtException(t, e);
                        return;
                    }
                    handler.handler(e);
                }
            });

     

     



    具体使用:在Application的onCreate中安装下,SecyrityCrash.install();

     

     

     

     

     

     

     

    public class MyApplication extends Application {
    
    
       @Override
       public void onCreate() {
            super.onCreate();
           SecyrityCrash.install();
        }
    
    
    }

     

     

      我默认实现了一个处理行为,EndCurrenPagerHandler、IgnoreHandler、KillAppHandler。由工厂IHandlerExceptionFactory构建。事实 我建议大家根据项目定义错误处理。

     setMainThreadFactory:主线程错误处理,用户可以自定义主线程处理逻辑 
    setChildThreadFactory:子线程错误处理,用户可以自定义主线程处理逻辑 
    setOnExceptionCallBack:异常通知,如果想在外部接收异常,可以通过这个回调,如果你想将异常信息上传到服务器。

     

     

     

    展开全文
  • 除了一直屏幕亮着,有其他方法吗???看到一个11年的帖子有同样问题,可是楼主最后却没说解决方法……那个帖子提到服务可以不受影响,我试过不行啊。 初学者,这个问题也许对各位很简单,可是困扰了我很长时间了...
  • 需求:按当前项目工程的组织结构,业务模块被分为多个独立的Module,要求当业务模块内发生未捕获到的局部异常时,不重启整个应用,只是单独重启某个异常的业务模块 目前安卓中常用的异常捕获有两种方式: 一种是局部...

    需求:按当前项目工程的组织结构,业务模块被分为多个独立的Module,要求当业务模块内发生未捕获到的局部异常时,不重启整个应用,只是单独重启某个异常的业务模块

    目前安卓中常用的异常捕获有两种方式:

    一种是局部异常捕获,使用try catch包括目标代码块

    一种是使用Thread.setDefaultUncaughtExceptionHandler捕获全局异常,但主线程发生异常使用此种方式捕获,应用必将崩溃或重启,无法做到只重启某业务模块

    显然两种方式都无法满足需求,那么此时还有另外一种出现全局异常不崩溃,更优雅的异常处理方式:

    接管主线程的Looper.loop()方法,并且使用try catch包括它,判断业务模块的包名,重启目标业务模块,完美满足需求


    安卓应用启动时,会初始化ActivityThread对象,调用其main方法,在main方法中又调用了Looper.loop()方法,来开启消息循环,处理所有主线程操作

    主线程所发生的所有异常,追踪其源头都是Looper.loop方法,接管该方法,即可将主线程出现的任何异常都正确捕获处理了,那么子线程呢


    大家都知道子线程默认是没有Looper的,此时可以用捕获全局异常的方式来处理子线程的异常,全局捕获子线程异常,不会导致应用崩溃


     

    两种方式相结合,可以处理应用中的所有异常,并使应用能够正常运行下去。

     

     

     

     

    展开全文
  • Unity 导出安卓让应用后台运行

    千次阅读 2017-07-04 17:28:31
    1.点击home键进入后台运行: 在AndroidManifest 中加入 : android:configChanges=”fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|...

    1.点击home键进入后台运行:
    在AndroidManifest 中加入 :

    android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"

    这里写图片描述


    2.点击back键也进入到后台运行,只需要在点击返回键的时候调用安卓这边的方法。

       static public void onExit()
        {
            Activity unityActivity = UnityPlayer.currentActivity;
            unityActivity.moveTaskToBack(false);
        }

    主要是moveTaskToBack(false)方法,unity这边如何调用可以按自己的习惯进行编写

    展开全文
  • 如何你的App永远在后台存活:对Android进程守护、闹钟后台被杀死的研究。 最近公司要求要做一个提醒功能,一说到提醒,那肯定就和闹钟差不多的意思,那么肯定就要用到AlarmManager。 但是,我们知道,android...
  • Dapr是一个开源、可移植、事件驱动的云原生分布式应用运行时,它使开发人员能够轻松地构建运行在云平台和边缘的弹性而微服务化的无状态和有状态的应用程序,从而降低基于微服务架构构建现代云原生应用的准入门槛。...
  • 点击关闭应用应用好像并没有关闭,不说中间曲折的探索之路的,最后的解决方案就是我的app中只修改了一行: 在module的gradle文件中把原来的25改成了22就好了,再也不弹出这个该死的框了。 targetSdk...
  • 如何在关闭ssh连接的情况下,程序继续运行?对Unix,Linux类服务器维护经常是通过ssh完成的,而有些操作比较费时,如更新程序等。此时如果断开ssh连接的话,更新程序就会随之被中断。如何保证断开ssh后仍旧能保持...
  • 下面有两种解决方法,第一种是类似if…else…;另外一种是使用语句来实现继续...1.在应用程序遇到异常情况(如被零除情况或内存不足警告)时,就会产生异常。 2.发生异常时,控制流立即跳转到关联的异常处理程序(...
  • 有什么办法可以安卓Service在关闭进程后继续运行?最好不要是重启Service
  • iOS应用程序运行原理及各步骤解析

    千次阅读 2015-09-01 10:20:12
    1. Not running:应用还没有启动,或者应用正在运行但是途中被系统停止。 [码农也需要休息吧,不能每天无休止的干下去,万一哪天来个猝死,老婆孩子怎么办,父母怎么办?中国有哪个公司一样,能像Google一样替你...
  • 1,程序的挂起和退出 由于iOS设备资源有限。当用户点击了home键,或者另一个应用程序启动了。那么原先那个程序便进入后台被挂起,不是退出,只是停止...当应用程序恢复时,它会从停止的位置重新开始。2,如下特殊的应
  • Chrome 在后台运行

    万次阅读 2019-11-15 09:45:53
    如何谷歌浏览器(google chrome)在后台运行 打开谷歌浏览器(google chrome),点击小编红框标记位置,点击设置: ...继续滚动鼠标到最底部,勾选 “关闭 google chrome 后继续 运行后台应用” ...
  • 浏览器访问NC时提示已阻止自签名的应用程序运行处理方案一、如图所示提示错误二、先按照浏览器提示下载安装java1.7版本,安装完成在控制面板的程序中打开Java三、弹出界面 选择“安全”四、接着选择“编辑站点列表”...
  • 运行应用软件时可能会遇到各种情况,如在打开软件的执行程序时提示缺少*.dll的文件,导致应用程序无法正常运行,根据已解决的案列,可采用下载新的*.dll文件,然后再放置到应用程序的安装目录中,问题基本可以解决...
  • [Applet]Chrome中运行Applet应用

    万次阅读 2015-09-04 11:49:37
    由于对安全级别的设置,Java 8中对本地Applet应用程序的运行有安全要求。在Chrome浏览器中运行Applet应用的.html文件,因为受到Java因安全问题的阻止而无法运行。需要对其设置一下。 Java插件安装 Firefox浏览器...
  • 前言:像默认授予预制应用这个方法还是不好百度到的,用到的人不多,自己总结下最近的学习成果,方便...该模式将需要危险权限(请参阅受影响的权限)的 Android 应用从安装时权限模式转移至运行时权限模式:安装时权...
  • 这些特定的资源或者类构成了Android应用程序的运行上下文环境,Android应用程序窗口可以通过一个Context接口来访问它,这个Context接口也是我们在开发应用程序时经常碰到的。在本文中,我们就将详细分析Android应用...
  • VS控制台程序被暂停,回车继续运行

    千次阅读 2019-01-22 22:59:21
    后来多次实验发现敲一个回车键程序又会继续运行,才发现是是vs控制台提供的暂停功能,即控制台连续打印过程中,鼠标单击控制台的界面(控制台边框内)程序会暂停,打印也停止,可以方便查看打印信息,点回车键后又会...
  • ios应用在后台运行时间讨论

    千次阅读 2014-09-02 17:53:26
    ios7系统中, 如果应用进入后台时,它并没有彻底进入后台, 而是有默认的10秒运行时间,
  • 环境:CentOS 7 前提条件:服务器已经安装了screen,如果未安装执行命令 yum install screen 1.创建screen会话 screen -S wordname #wordname...2.输入需要运行程序的命令 例如 ./start.sh 3.关闭窗口 Crt...
  • 如何保证断开ssh后仍旧能保持更新进程的运行呢?有两种方法:   (1)nohup   #nohup 应用程序名 &   此后,如果你断开了ssh,程序依旧运行。此种方式的缺点是,应用程序没有交互界面了,程序...
  • 如果您要构建 Node.js 应用程序,那么可以使用 IBM® ...执行更改后,您可以立即在运行中的 Bluemix 应用程序中看到该更改。Bluemix Live Sync 可从命令行以及在 Web IDE 中运行。您可以使用 Bluemix Live Sync 来调试
  •         ...然后,我将向您展示如何在Android模拟器或实际设备(在本例中为Kindle Fire平板电脑)上设置和运行应用程序。我还将向您展示如何解决Androi
  • 先决条件 为了从本文中获得最大收益,您应该具有在Windows环境中使用桌面应用程序的经验。 我假设读者对如何使用Linux桌面有基本的了解。... 有时,第一次在Linux上运行应用程序需要一些额外的工作。 某些...
  • 我们接着上篇,已经编译好镜像,本篇将介绍两种启动方式,交互模式启动和后台线程启动 1、交互模式启动 docker run -it -p 80:12345 ... 运行后效果如下,因为是交互模式所以当前会话不支持继续输入命令工作,如...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 893,561
精华内容 357,424
关键字:

怎么让应用继续运行