BaseActivity+Application的使用,捕捉异常自动重启应用

来源:互联网 发布:Nginx反向代理80配置 编辑:程序博客网 时间:2024/04/28 11:45

在网上找了一些BaseActivity的实现,现结合Application,方便android应用开发
下面用一个例子说明,程序捕捉到异常后自动重新启动。

package com.brian.example;import android.os.Bundle;public class MainActivity extends BaseActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);iniView();}@Overridevoid iniView() {System.out.println("hello");int[] ints = new int[1];System.out.println(ints[1]);//数组溢出,如果不做处理则会显示程序停止运行}}


Application类的实现,负责应用程序全局异常的捕捉。

package com.brian.example;import java.io.File;import java.io.FileOutputStream;import java.io.PrintWriter;import java.io.StringWriter;import java.io.Writer;import java.lang.Thread.UncaughtExceptionHandler;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Locale;import android.app.Activity;import android.app.AlarmManager;import android.app.Application;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.os.Environment;/** * 1、收集所有 avtivity 用于彻底退出应用 * 2、捕获崩溃异常,保存错误日志,并重启应用 */public class MyApplication extends Application {// activity对象列表,用于activity统一管理private List<Activity> activityList;// 异常捕获protected boolean isNeedCaughtExeption = true;// 是否捕获未知异常private PendingIntent restartIntent;private MyUncaughtExceptionHandler uncaughtExceptionHandler;private String packgeName;@Overridepublic void onCreate() {super.onCreate();activityList = new ArrayList<Activity>();packgeName = getPackageName();if (isNeedCaughtExeption) {cauchException();}}// -------------------异常捕获-----捕获异常后重启应用-----------------//private void cauchException() {Intent intent = new Intent();// 参数1:包名,参数2:程序入口的activityintent.setClassName(packgeName, packgeName + ".MainActivity");//设置程序入口restartIntent = PendingIntent.getActivity(getApplicationContext(), -1, intent,Intent.FLAG_ACTIVITY_NEW_TASK);// 程序崩溃时触发线程uncaughtExceptionHandler = new MyUncaughtExceptionHandler();Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);}// 创建服务用于捕获崩溃异常private class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {@Overridepublic void uncaughtException(Thread thread, Throwable ex) {// 保存错误日志saveCatchInfo2File(ex);// 1秒钟后重启应用AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent);// 关闭当前应用finishAllActivity();finishProgram();}};/** * 保存错误信息到文件中 *  * @return 返回文件名称 */private String saveCatchInfo2File(Throwable ex) {Writer writer = new StringWriter();PrintWriter printWriter = new PrintWriter(writer);ex.printStackTrace(printWriter);Throwable cause = ex.getCause();while (cause != null) {cause.printStackTrace(printWriter);cause = cause.getCause();}printWriter.close();String sb = writer.toString();try {DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.CHINA);String time = formatter.format(new Date());String fileName = time + ".txt";System.out.println("fileName:" + fileName);if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {String filePath = Environment.getExternalStorageDirectory() + "/HKDownload/" + packgeName+ "/crash/";File dir = new File(filePath);if (!dir.exists()) {if (!dir.mkdirs()) {// 创建目录失败: 一般是因为SD卡被拔出了return "";}}System.out.println("filePath + fileName:" + filePath + fileName);FileOutputStream fos = new FileOutputStream(filePath + fileName);fos.write(sb.getBytes());fos.close();//文件保存完了之后,在应用下次启动的时候去检查错误日志,发现新的错误日志,就发送给开发者}return fileName;} catch (Exception e) {System.out.println("an error occured while writing file..." + e.getMessage());}return null;}// ------------------------------activity管理-----------------------//// activity管理:从列表中移除activitypublic void removeActivity(Activity activity) {activityList.remove(activity);}// activity管理:添加activity到列表public void addActivity(Activity activity) {activityList.add(activity);}// activity管理:结束所有activitypublic void finishAllActivity() {for (Activity activity : activityList) {if (null != activity) {activity.finish();}}}// 结束线程,一般与finishAllActivity()一起使用// 例如: finishAllActivity;finishProgram();public void finishProgram() {finishAllActivity();android.os.Process.killProcess(android.os.Process.myPid());}}

基类BaseActivity实现了接口IBaseActivity

package com.brian.example;import android.app.Application;import android.app.ProgressDialog;import android.content.Context;import android.content.SharedPreferences;/** * Activity的支持类接口,主要定义了Activity中常用的功能 */public interface IBaseActivity {/** * 获取Application对象 * @return */public abstract Application getApplication();/** * 开启服务 */public abstract void startService();/** * 停止服务 */public abstract void stopService();/** * 判断是否有网络连接,若没有,则弹出网络设置对话框,返回false */public abstract boolean validateInternet();/** * 判断是否有网络连接,没有返回false */public abstract boolean hasInternetConnected();/** * 退出应用 */public abstract void isExit();/** * 判断GPS是否已经开启. */public abstract boolean hasLocationGPS();/** * 判断基站是否已经开启. */public abstract boolean hasLocationNetWork();/** * 检查内存卡. */public abstract void checkMemoryCard();/** * 获取进度条. */public abstract ProgressDialog getProgressDialog();/** * 返回当前Activity上下文. */public abstract Context getContext();/** * 获取当前登录用户的SharedPreferences配置. */public SharedPreferences getLoginUserSharedPre();/** * 用户是否在线(当前网络是否重连成功) */public boolean getUserOnlineState();/** * 设置用户在线状态 true 在线 false 不在线 */public void setUserOnlineState(boolean isOnline);/** * 发出Notification的method. *  * @param iconId 图标 * @param contentTitle  标题 * @param contentText 内容 * @param activity */public void PushNotification(int iconId, String contentTitle, String contentText, Class<?> activity, String from);}

基类根据需要(各界面都可能用到的操作或属性)添加相应个操作和属性:

package com.brian.example;import android.app.Activity;import android.app.AlertDialog;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.ProgressDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.SharedPreferences;import android.location.LocationManager;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Bundle;import android.os.Environment;import android.provider.Settings;import android.view.inputmethod.InputMethodManager;/** * Activity的基类,实现了IActivitySupport接口 */public abstract class BaseActivity extends Activity implements IBaseActivity {protected Context mContext = null;protected SharedPreferences preferences;protected MyApplication myApplication;protected ProgressDialog pg = null;protected NotificationManager notificationManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContext = this;preferences = getSharedPreferences("TAG", 0);notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);pg = new ProgressDialog(mContext);myApplication = (MyApplication) this.getApplication();}/** * 初始化页面布局 */abstract void iniView();@Overridepublic ProgressDialog getProgressDialog() {return pg;}/** * 在这里开启所有需要开启的服务 */@Overridepublic void startService() {}/** * 在这里关闭所有需要开启的服务 */@Overridepublic void stopService() {}/** * 停止服务并结束所有的Activity退出应用 */@Overridepublic void isExit() {new AlertDialog.Builder(mContext).setTitle("确定退出吗?").setNeutralButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {stopService();myApplication.finishProgram();}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.cancel();}}).show();}/** * 判断是否有网络连接,没有返回false */@Overridepublic boolean hasInternetConnected() {ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);if (manager != null) {NetworkInfo network = manager.getActiveNetworkInfo();if (network != null && network.isConnectedOrConnecting()) {return true;}}return false;}/** * 判断是否有网络连接,若没有,则弹出网络设置对话框,返回false */@Overridepublic boolean validateInternet() {ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);if (manager == null) {openWirelessSet();return false;} else {NetworkInfo[] info = manager.getAllNetworkInfo();if (info != null) {for (int i = 0; i < info.length; i++) {if (info[i].getState() == NetworkInfo.State.CONNECTED) {return true;}}}}openWirelessSet();return false;}/** * 判断GPS定位服务是否开启 */@Overridepublic boolean hasLocationGPS() {LocationManager manager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);if (manager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {return true;} else {return false;}}/** * 判断基站定位是否开启 */@Overridepublic boolean hasLocationNetWork() {LocationManager manager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);if (manager.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER)) {return true;} else {return false;}}/** * 检查内存卡可读 */@Overridepublic void checkMemoryCard() {if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {new AlertDialog.Builder(mContext).setTitle("检测内存卡").setMessage("请检查内存卡").setPositiveButton("设置",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.cancel();Intent intent = new Intent(Settings.ACTION_SETTINGS);mContext.startActivity(intent);}}).setNegativeButton("退出",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.cancel();}}).create().show();}}/** * 打开网络设置对话框 */public void openWirelessSet() {AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);dialogBuilder.setTitle("网络设置").setMessage("检查网络").setPositiveButton("网络设置",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {dialog.cancel();Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);mContext.startActivity(intent);}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int whichButton) {dialog.cancel();}});dialogBuilder.show();}/** * 关闭键盘 */public void closeInput() {InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);if (inputMethodManager != null && this.getCurrentFocus() != null) {inputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);}}/** * 发出Notification * @param iconId 图标 * @param contentTitle 标题 * @param contentText 内容 * @param activity */@SuppressWarnings("deprecation")public void PushNotification(int iconId, String contentTitle,String contentText, Class<?> activity, String to) {// 创建新的Intent,作为点击Notification留言条时, 会运行的ActivityIntent notifyIntent = new Intent(this, activity);notifyIntent.putExtra("to", to);// 创建PendingIntent作为设置递延运行的ActivityPendingIntent appIntent = PendingIntent.getActivity(mContext, 0, notifyIntent, 0);/* 创建Notication,并设置相关参数 */Notification myNoti = new Notification();// 点击自动消失myNoti.flags = Notification.FLAG_AUTO_CANCEL;/* 设置statusbar显示的icon */myNoti.icon = iconId;/* 设置statusbar显示的文字信息 */myNoti.tickerText = contentTitle;/* 设置notification发生时同时发出默认声音 */myNoti.defaults = Notification.DEFAULT_SOUND;/* 设置Notification留言条的参数 */myNoti.setLatestEventInfo(mContext, contentTitle, contentText, appIntent);/* 送出Notification */notificationManager.notify(0, myNoti);}/** * 返回上下文对象 */@Overridepublic Context getContext() {return mContext;}/** * 返回登录用户的SharedPreferences对象 */@Overridepublic SharedPreferences getLoginUserSharedPre() {return preferences;}/** * 获取用户在线状态 */@Overridepublic boolean getUserOnlineState() {return false;}/** * 设置用户在线状态 */@Overridepublic void setUserOnlineState(boolean isOnline) {}}

使用MyApplication需要在清单文件里面配置:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.brian.example"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="18" />    <application        android:name="com.brian.example.MyApplication"        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.brian.example.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

其他功能还需要添加相应的权限,上述代码运行的效果就是,程序会不停地重启,后台会打印hello,但是界面不会显示helloworld


0 0
原创粉丝点击