在网上找了一些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