首页 > 代码库 > 如何保证android程序进程不到万不得已的情况下,不会被结束

如何保证android程序进程不到万不得已的情况下,不会被结束

最近,做一个调用系统自带相机的那么一个功能,遇到的坑,在此记录一下。
设备:红米note4

问题起因

因为自定义的相机,很难满足客户的所有需要,比如:自拍杆的支持,优化方面等等。这些方面自定义的相机都不比系统自带的好,因为有些系统都是商家定制的,难免会出现一个奇葩的问题。比如:你在这款手机上运行,无任何问题,然而你换一款手机后,问题就出现了。

比如:小米的红米系列,你启用系统自带拍照功能后,当前的所有进程都会被结束了(包含:其它正在运行的程序)。当你拍照完成,返回时,问题出现了,总会报些空指针。

虽然调用了系统相机,进程会被结束掉,但返回时被结束的进程被重新启动,但这时你之前保存的值都没了(activity会重新启动oncreate流程,application会重新初始化)。
当然你会说,完全可以在activity中的onSaveInstanceState方法中保存值,等恢复再取出。但如果是application呢?那又怎么恢复。如果你的业务够复杂,那数据真不好恢复,比如:你的主体是activity,activity中又有若干个Fragment,各个Fragment又取值于application,这些就麻烦多多,恢复都麻烦。

解决方案

在前台运行服务
看官方描述:https://developer.android.com/guide/components/services.html

前台服务被认为是用户主动意识到的一种服务,因此在内存不足时,系统也不会考虑将其终止。 前台服务必须为状态栏提供通知,放在“正在进行”标题下方,这意味着除非服务停止或从前台移除,否则不能清除通知。
例如,应该将通过服务播放音乐的音乐播放器设置为在前台运行,这是因为用户明确意识到其操作。 状态栏中的通知可能表示正在播放的歌曲,并允许用户启动 Activity 来与音乐播放器进行交互。

需要在服务里使用startForeground方法

Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
        System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
        getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);

实现代码

NotificationService.java

package xxx;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.hkcg.mrsi.MyApplication;
import com.hkcg.mrsi.R;

/**
 * 
 * @author Aaron
 * @version 1.0
 * @createTime 2016-12-20
 * @desc <br>
 * @usage
 */
public class NotificationService extends Service {
    private static Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
    private static NotificationManager mNotificationManager = (NotificationManager) MyApplication.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
    private static final String TAG = "NotificationService";

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        Log.i(TAG, "onCreate");
        super.onCreate();
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand");
        Notification notification = createNotificationTip(0x689,this, "title", "为确保正常运行,请不要结束程序运行。",null);
        startForeground(0x689, notification);
        flags = START_STICKY;
        return super.onStartCommand(intent, flags, startId);
    }


    public Notification createNotificationTip(int id,Context context, String title, String content, Integer icon) {
        icon = icon == null ? R.drawable.ic_launcher : icon;
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                .setSmallIcon(icon)//小图标
                .setContentTitle(title) // 标题
                .setContentText(content)// 内容
                .setOngoing(true) // 是否正在进行
                .setPriority(Notification.PRIORITY_MAX);//通知优先级
        Notification notification = mBuilder.build();
        mNotificationManager.notify(id, notification);
        return notification;
    }

}

AndroidManifest.xml


        <service  
          android:name="com.hkcg.mrsi.loc.NotificationService"  
          android:enabled="true" >
        </service>

调用

startService(new Intent(this, NotificationService.class));
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    如何保证android程序进程不到万不得已的情况下,不会被结束