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

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

package com.brian.example;

import android.os.Bundle;

public class MainActivity extends BaseActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		iniView();
	}

	@Override
	void 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;

	@Override
	public void onCreate() {
		super.onCreate();

		activityList = new ArrayList<Activity>();
		packgeName = getPackageName();

		if (isNeedCaughtExeption) {
			cauchException();
		}
	}

	// -------------------异常捕获-----捕获异常后重启应用-----------------//

	private void cauchException() {
		Intent intent = new Intent();
		// 参数1:包名,参数2:程序入口的activity
		intent.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 {
		@Override
		public 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管理:从列表中移除activity
	public void removeActivity(Activity activity) {
		activityList.remove(activity);
	}

	// activity管理:添加activity到列表
	public void addActivity(Activity activity) {
		activityList.add(activity);
	}

	// activity管理:结束所有activity
	public 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实现了接口I BaseActivity

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;

	@Override
	protected 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();

	@Override
	public ProgressDialog getProgressDialog() {
		return pg;
	}

	/**
	 * 在这里开启所有需要开启的服务
	 */
	@Override
	public void startService() {

	}

	/**
	 * 在这里关闭所有需要开启的服务
	 */
	@Override
	public void stopService() {

	}

	/**
	 * 停止服务并结束所有的Activity退出应用
	 */
	@Override
	public void isExit() {
		new AlertDialog.Builder(mContext).setTitle("确定退出吗?")
				.setNeutralButton("确定", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						stopService();
						myApplication.finishProgram();
					}
				})
				.setNegativeButton("取消", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				}).show();
	}

	/**
	 * 判断是否有网络连接,没有返回false
	 */
	@Override
	public 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
	 */
	@Override
	public 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定位服务是否开启
	 */
	@Override
	public boolean hasLocationGPS() {
		LocationManager manager = (LocationManager) mContext
				.getSystemService(Context.LOCATION_SERVICE);
		if (manager
				.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断基站定位是否开启
	 */
	@Override
	public boolean hasLocationNetWork() {
		LocationManager manager = (LocationManager) mContext
				.getSystemService(Context.LOCATION_SERVICE);
		if (manager
				.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 检查内存卡可读
	 */
	@Override
	public void checkMemoryCard() {
		if (!Environment.MEDIA_MOUNTED.equals(Environment
				.getExternalStorageState())) {
			new AlertDialog.Builder(mContext)
					.setTitle("检测内存卡")
					.setMessage("请检查内存卡")
					.setPositiveButton("设置",
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog, int which) {
									dialog.cancel();
									Intent intent = new Intent(Settings.ACTION_SETTINGS);
									mContext.startActivity(intent);
								}
							})
					.setNegativeButton("退出",
							new DialogInterface.OnClickListener() {
								@Override
								public 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() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								dialog.cancel();
								Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
								mContext.startActivity(intent);
							}
						})
				.setNegativeButton("取消", new DialogInterface.OnClickListener() {
					@Override
					public 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留言条时, 会运行的Activity
		Intent notifyIntent = new Intent(this, activity);
		notifyIntent.putExtra("to", to);
		// 创建PendingIntent作为设置递延运行的Activity
		PendingIntent 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);
	}

	/**
	 * 返回上下文对象
	 */
	@Override
	public Context getContext() {
		return mContext;
	}

	/**
	 * 返回登录用户的SharedPreferences对象
	 */
	@Override
	public SharedPreferences getLoginUserSharedPre() {
		return preferences;
	}

	/**
	 * 获取用户在线状态
	 */
	@Override
	public boolean getUserOnlineState() {
		return false;
	}

	/**
	 * 设置用户在线状态
	 */
	@Override
	public 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值