Android BaseActivity App框架设计BaseActivity封装
2016-10-29 16:17
507 查看
Android BaseActivity 分享
在Android开发中,为了更好的对栈堆中的Activity进行管理以及更有效的对程序中可复用的方法进行复用,我们通常会为程序写一个Activity的基类,这次我就分享一个Activity基类的基本写法。希望能够帮助到兄弟姐妹们。在开发的过程中,Activity通常会使用到FragmentActivity而FragmentActivity是继承Activity的所以们新建一个Activity让他继承FragmentActivity。
import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class KxActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
接下来,我们给他加上一些通用的方法,让你的代码结构更加清晰,简洁。
首先,写一个接口,让KxActivity进行实现,覆写里面的方法:
public interface Interface_KxActivity { /** * 初始化界面 (在这里进行layout设置) */ void initRoot(); /** * 初始化控件 */ void stupView(); /** * 初始化数据 */ void stupData(); /** * 点击事件回调方法 * @param view 被点击的控件 */ void viewClick(View view); /** * 设置是否是碎片Activity * @param is */ void isFragmentActivity(boolean is); }
好了,那么我们再来写一个跳转页面以及关闭应用的接口:
public interface Show_KxActivity { /** * 关闭当前Activity跳转 * @param activity 当前Activity * @param cls 要跳转的Activity */ void finshTogo(Activity activity, Class<?> cls); /** * 关闭当前Activity跳转 * @param activity 当前Activity * @param intent intent活动 */ void finshTogo(Activity activity, Intent intent); /** * 关闭当前Activity跳转 * @param activity 当前Activity * @param cls 要跳转的Activity * @param bundle Bundle对象 */ void finshTogo(Activity activity, Class<?> cls, Bundle bundle); /** * 不关闭当前Activity跳转 * @param activity 当前Activity * @param cls 要跳转的Activity */ void keepTogo(Activity activity, Class<?> cls); /** * 不关闭当前Activity跳转 * @param activity 当前Activity * @param intent intent活动 */ void keepTogo(Activity activity, Intent intent); /** * 不关闭当前Activity跳转 * @param activity 当前Activity * @param cls 要跳转的Activity * @param bundle Bundle对象 */ void keepTogo(Activity activity, Class<?> cls, Bundle bundle); /** * 结果返回页面跳转 * @param intent Intent对象 * @param requestCode 访问代码 */ void forResultTogo(Intent intent,int requestCode); /** * 接收跳转页面的结果 * @param requestCode 访问代码 * @param resultCode 返回代码 * @param intent Intent对象 */ void OnKxActivityResult(int requestCode, int resultCode, Intent intent); /** * 杀死整个程序 */ void finishApp(); }
这些都写好了之后我们还有个比较常用的,那就是logcat,这里我也把它写成一个接口,这里我们进行配置是否打印logcat等处理,这里我只写了个logcat,其他的以后慢慢完善:
public interface Configer_KxActivity { /** * 设置是否显示debug logcat * @param isDebug 是否显示debug数据 */ void setIsDebug(boolean isDebug); }
ok,接下来我们再把Logcat封装一下,这里我借鉴了一位大神的封装,并进行了一些改动,毕竟好东西要大家分享嘛。。不过现在我没找到这个的链接了,如果有冒犯的地方还请见谅,一共三个类,我还是贴出来大家学习指正下:
import android.text.TextUtils; import android.util.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * Created by ouqikang on 15/11/16. */ public class Logger implements Printer{ private static final int DEBUG = 1; private static final int ERROR = 2; private static final int VERBOSE = 3; private static final int ASSERT = 4; private static final int INFO = 5; private static final int WARN = 6; private static final int JSON = 7; private static final int OBJECT = 8; private static final String LINE_SEPARATOR = System.getProperty("line.separator"); private static final char TOP_LEFT_CORNER = '╔'; private static final char BOTTOM_LEFT_CORNER = '╚'; private static final char MIDDLE_CORNER = '╟'; private static final char HORIZONTAL_DOUBLE_LINE = '║'; private static final String DOUBLE_DIVIDER = "════════════════════════════════════════════"; private static final String SINGLE_DIVIDER = "────────────────────────────────────────────"; private static final String TOP_BORDER = TOP_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER; private static final String BOTTOM_BORDER = BOTTOM_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER; private static final String MIDDLE_BORDER = MIDDLE_CORNER + SINGLE_DIVIDER + SINGLE_DIVIDER; @Override public void d(StackTraceElement element,String message,Object... args) { printLog(element,DEBUG,message,args); } @Override public void v(StackTraceElement element,String message,Object... args) { printLog(element,VERBOSE,message,args); } @Override public void a(StackTraceElement element,String message,Object... args) { printLog(element,ASSERT,message,args); } @Override public void i(StackTraceElement element,String message,Object... args) { printLog(element,INFO,message,args); } @Override public void e(StackTraceElement element,String message,Object... args) { printLog(element,ERROR, message,args); } @Override public void w(StackTraceElement element,String message,Object... args) { printLog(element, WARN, message, args); } @Override public void json(StackTraceElement element,String message) { printJson(element, message); } @Override public void object(StackTraceElement element,Object object) { printObject(element,object); } private void printJson(StackTraceElement element,String json){ if (!MyLog.configAllowLog){ return; } String[] values = generateValues(element); String tag = values[0]; String fileName = values[1]; if (TextUtils.isEmpty(json)){ Log.e(tag,"JSON{json is null}"); return; } try { if (json.startsWith("{")){ JSONObject jsonObject = new JSONObject(json); json = jsonObject.toString(4); }else if (json.startsWith("[")){ JSONArray array = new JSONArray(json); json = array.toString(4); } String[] lines = json.split(LINE_SEPARATOR); StringBuilder stringBuilder = new StringBuilder(); Log.e(fileName,TOP_BORDER); Log.e(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.e(fileName,MIDDLE_BORDER); for (String line: lines){ stringBuilder.append("║ ").append(line).append(LINE_SEPARATOR); Log.e(fileName,stringBuilder.toString()); stringBuilder.delete(0, stringBuilder.length()); } Log.e(fileName,BOTTOM_BORDER); }catch (JSONException e){ Log.e(tag,e.getMessage() ); } } private void printObject(StackTraceElement element,Object object){ if (!MyLog.configAllowLog){ return; } if (object == null){ printLog(element,ERROR,"object = null"); return; } String[] values = generateValues(element); String tag = values[0]; String fileName = values[1]; String simpleName = object.getClass().getSimpleName(); if (object instanceof String){ printLog(element,DEBUG,object.toString()); }else if (object instanceof Collection){ Collection collection = (Collection) object; String msg = " %s size = %d [\n"; msg = String.format(msg,simpleName,collection.size()); if (!collection.isEmpty()) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(TOP_BORDER).append(LINE_SEPARATOR) .append(HORIZONTAL_DOUBLE_LINE).append(" ").append(tag).append(LINE_SEPARATOR) .append(MIDDLE_BORDER).append(LINE_SEPARATOR) .append(HORIZONTAL_DOUBLE_LINE).append(msg); Iterator<Object> iterator = collection.iterator(); int index = 0; while (iterator.hasNext()){ String itemString = HORIZONTAL_DOUBLE_LINE + " [%d]:%s%s"; Object item = iterator.next(); stringBuilder.append(String.format(itemString,index, SystemUtil.objectToString(item),index++ < collection.size()-1?",\n":"\n")); } stringBuilder.append(HORIZONTAL_DOUBLE_LINE + " ]\n").append(BOTTOM_BORDER); Log.e(fileName,stringBuilder.toString()); }else { printLog(element,ERROR,msg + " and is empty ]"); } }else if (object instanceof Map){ Map<Object,Object> map = (Map<Object, Object>) object; Set<Object> keys = map.keySet(); if (keys.size() > 0) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(TOP_BORDER).append(LINE_SEPARATOR) .append(HORIZONTAL_DOUBLE_LINE).append(" ").append(tag).append(LINE_SEPARATOR) .append(MIDDLE_BORDER).append(LINE_SEPARATOR) .append(HORIZONTAL_DOUBLE_LINE).append(" ").append(simpleName).append(" {\n"); for (Object key : keys){ stringBuilder.append(HORIZONTAL_DOUBLE_LINE).append(" ") .append(String.format("[%s -> %s]\n",SystemUtil.objectToString(key),SystemUtil.objectToString(map.get(key)))); } stringBuilder.append(HORIZONTAL_DOUBLE_LINE).append(" ").append("}\n") .append(BOTTOM_BORDER); Log.e(fileName,stringBuilder.toString()); }else { printLog(element,ERROR,simpleName + " is Empty"); } }else { String message = SystemUtil.objectToString(object); Log.e(fileName,TOP_BORDER); Log.e(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.e(fileName,MIDDLE_BORDER); Log.e(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.e(fileName,BOTTOM_BORDER); } } private void printLog(StackTraceElement element,int logType, String message,Object... args){ if (!MyLog.configAllowLog){ return; } String[] values = generateValues(element); String tag = values[0]; String fileName = values[1]; if (TextUtils.isEmpty(message)){ Log.e(tag,"log message is null"); return; } if (args.length > 0){ message = String.format(message,args); } switch (logType){ case ERROR: Log.e(fileName,TOP_BORDER); Log.e(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.e(fileName,MIDDLE_BORDER); Log.e(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.e(fileName,BOTTOM_BORDER); break; case VERBOSE: Log.v(fileName,TOP_BORDER); Log.v(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.v(fileName,MIDDLE_BORDER); Log.v(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.v(fileName,BOTTOM_BORDER); break; case INFO: Log.i(fileName,TOP_BORDER); Log.i(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.i(fileName,MIDDLE_BORDER); Log.i(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.i(fileName,BOTTOM_BORDER); break; case ASSERT: Log.wtf(fileName,TOP_BORDER); Log.wtf(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.wtf(fileName,MIDDLE_BORDER); Log.wtf(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.wtf(fileName,BOTTOM_BORDER); break; case WARN: Log.w(fileName,TOP_BORDER); Log.w(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.w(fileName,MIDDLE_BORDER); Log.w(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.w(fileName,BOTTOM_BORDER); break; case DEBUG: Log.d(fileName,TOP_BORDER); Log.d(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.d(fileName,MIDDLE_BORDER); Log.d(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.d(fileName,BOTTOM_BORDER); break; case OBJECT: Log.d(fileName,TOP_BORDER); Log.d(fileName,HORIZONTAL_DOUBLE_LINE + " " + tag); Log.d(fileName,MIDDLE_BORDER); Log.d(fileName, HORIZONTAL_DOUBLE_LINE + " " + message); Log.d(fileName,BOTTOM_BORDER); break; } } private String[] generateValues(StackTraceElement element){ String[] values = new String[2]; StackTraceElement traceElement = element; StringBuilder sb = new StringBuilder(); String className = traceElement.getClassName(); String fileName = traceElement.getFileName(); sb.append(className.substring(className.lastIndexOf(".") + 1)).append(".").append(traceElement.getMethodName()) .append(" (").append(fileName).append(":").append(traceElement.getLineNumber()) .append(") "); String tag = sb.toString(); values[0] = tag; values[1] = fileName; return values; } }
/** * Created by ouqikang on 15/11/16. */ public class MyLog { /** * 是否允许输出log */ public static boolean configAllowLog = true; private static Logger logger; static { logger = new Logger(); } public static void d(String message,Object... args){ logger.d(SystemUtil.getStackTrace(),message,args); } public static void e(String message,Object... args){ logger.e(SystemUtil.getStackTrace(),message,args); } public static void i(String message,Object... args){ logger.i(SystemUtil.getStackTrace(),message,args); } public static void a(String message,Object... args){ logger.a(SystemUtil.getStackTrace(),message,args); } public static void w(String message,Object... args){ logger.w(SystemUtil.getStackTrace(),message,args); } public static void v(String message,Object... args){ logger.v(SystemUtil.getStackTrace(),message,args); } /** * 打印json * @param json */ public static void json(String json){ logger.json(SystemUtil.getStackTrace(),json); } /** * 打印对象(支持Collection,Map) * @param object */ public static void object(Object object){ logger.object(SystemUtil.getStackTrace(),object); } }
import java.lang.reflect.Field; /** * Created by ouqikang on 15/11/16. */ public class SystemUtil { /** * 获取StackTraceElement对象 * @return */ public static StackTraceElement getStackTrace(){ return Thread.currentThread().getStackTrace()[4]; } // 基本数据类型 private final static String[] types = {"int", "java.lang.String", "boolean", "char", "float", "double", "long", "short", "byte"}; /** * 将对象转化为String * * @param object * @return */ public static <T> String objectToString(T object) { if (object == null) { return "Object{object is null}"; } if (object.toString().startsWith(object.getClass().getName() + "@")) { StringBuilder builder = new StringBuilder(object.getClass().getSimpleName() + " { "); Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); boolean flag = false; for (String type : types) { if (field.getType().getName().equalsIgnoreCase(type)) { flag = true; Object value = null; try { value = field.get(object); } catch (IllegalAccessException e) { value = e; }finally { builder.append(String.format("%s=%s, ", field.getName(), value == null ? "null" : value.toString())); break; } } } if(!flag){ builder.append(String.format("%s=%s, ", field.getName(), "Object")); } } return builder.replace(builder.length() - 2, builder.length() - 1, " }").toString(); } else { return object.toString(); } } }
好了,干货分享完了,我们再来说说Activity管理吧,通过栈堆进行管理,我这里也是借鉴了 [ Activity管理类 ] 谢谢大神!
import android.app.Activity; import android.content.Context; import java.util.Stack; /** * Created by my on 2016/10/29. */ public class KxActivityStack { private static Stack<Activity> activityStack; private static KxActivityStack instance; private KxActivityStack() {} /** * 单一实例 */ public static KxActivityStack getAppManager() { if (instance == null) { instance = new KxActivityStack(); } return instance; } /** * 添加Activity到堆栈 */ public void addActivity(Activity activity) { if (activityStack == null) { activityStack = new Stack<Activity>(); } activityStack.add(activity); } /** * 获取当前Activity(堆栈中最后一个压入的) */ public Activity currentActivity() { Activity activity = activityStack.lastElement(); return activity; } /** * 结束当前Activity(堆栈中最后一个压入的) */ public void finishActivity() { Activity activity = activityStack.lastElement(); finishActivity(activity); } /** * 结束指定的Activity */ public void finishActivity(Activity activity) { if (activity != null && !activity.isFinishing()) { activityStack.remove(activity); activity.finish(); activity = null; } } /** * 结束指定类名的Activity */ public void finishActivity(Class<?> cls) { for (Activity activity : activityStack) { if (activity.getClass().equals(cls)) { finishActivity(activity); break; } } } /** * 结束所有Activity */ public void finishAllActivity() { for (int i = 0, size = activityStack.size(); i < size; i++) { if (null != activityStack.get(i)) { finishActivity(activityStack.get(i)); break; } } activityStack.clear(); } /** * 获取指定的Activity */ public static Activity getActivity(Class<?> cls) { if (activityStack != null) for (Activity activity : activityStack) { if (activity.getClass().equals(cls)) { return activity; } } return null; } /** * 退出应用程序 */ public void AppExit(Context context) { try { finishAllActivity(); // 杀死该应用进程 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); } catch (Exception e) { e.printStackTrace(); } } }
最后的封魔,需要继承的BaseActivity基类:
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.view.View; import com.kxactivity.interfaces.Configer_KxActivity; import com.kxactivity.interfaces.Interface_KxActivity; import com.kxactivity.interfaces.Show_KxActivity; import com.kxactivity.logcat.MyLog; import com.kxactivity.tools.KxActivityStack; /** * Activity的框架,程序中的Activity继承它后可以使用 * 创建时间:2016年10月29日 * 修改时间: * @author ThomsonKang */ public class KxActivity extends FragmentActivity implements Interface_KxActivity,View.OnClickListener,Show_KxActivity,Configer_KxActivity { public Activity mActivity; private FragmentManager fragmentManager; // 碎片管理 private boolean isFragmentActivity = false; // 是否是碎片Activity public static boolean isDebug = false; @Override protected void onCreate(Bundle savedInstanceState) { initializationMethod(); KxActivityStack.getAppManager().addActivity(mActivity); //将Activity添加进栈堆中 MyLog.e(KxActivityStack.getAppManager().currentActivity().getLocalClassName()+"开启"); super.onCreate(savedInstanceState); } @Override protected void onDestroy() { super.onDestroy(); } @Override protected void onPause() { super.onPause(); } @Override protected void onResume() { super.onResume(); } @Override protected void onStart() { super.onStart(); } @Override protected void onStop() { super.onStop(); } @Override public void initRoot() { } @Override public void stupView() { } @Override public void stupData() { } @Override public void viewClick(View view) { } /** * 如果是碎片Activity就返回一个碎片管理对象 * @param is 是否是碎片Activity */ @Override public void isFragmentActivity(boolean is) { isFragmentActivity = is; if (is){ fragmentManager = getSupportFragmentManager(); } } @Override public void onClick(View v) { viewClick(v); } /** * 初始化这个个Activity */ private void initializationMethod(){ mActivity = this; //方便子类调用 initRoot(); stupData(); stupView(); } /** * 关闭当前页面跳转 * @param activity 当前Activity * @param cls 要跳转的Activity */ @Override public void finshTogo(Activity activity, Class<?> cls) { keepTogo(activity, cls); activity.finish(); } /** * 关闭当前页面跳转 * @param activity 当前Activity * @param intent intent活动 */ @Override public void finshTogo(Activity activity, Intent intent) { keepTogo(activity, intent); activity.finish(); } /** * 关闭当前页面跳转 * @param activity 当前Activity * @param cls 要跳转的Activity * @param bundle Bundle对象 */ @Override public void finshTogo(Activity activity, Class<?> cls, Bundle bundle) { keepTogo(activity, cls, bundle); activity.finish(); } /** * 不关闭当前页面跳转 * @param activity 当前Activity * @param cls 要跳转的Activity */ @Override public void keepTogo(Activity activity, Class<?> cls) { Intent intent = new Intent(); intent.setClass(activity, cls); activity.startActivity(intent); } /** * 不关闭当前页面跳转 * @param activity 当前Activity * @param intent intent活动 */ @Override public void keepTogo(Activity activity, Intent intent) { activity.startActivity(intent); } /** * 不关闭当前页面跳转 * @param activity 当前Activity * @param cls 要跳转的Activity * @param bundle Bundle对象 */ @Override public void keepTogo(Activity activity, Class<?> cls, Bundle bundle) { Intent intent = new Intent(); intent.putExtras(bundle); intent.setClass(activity, cls); activity.startActivity(intent); } /** * 返回结果页面跳转 * @param intent Intent对象 * @param requestCode 访问代码 */ @Override public void forResultTogo(Intent intent, int requestCode) { startActivityForResult(intent,requestCode); } /** * 接收跳转页面的结果返回 * @param requestCode 访问代码 * @param resultCode 返回代码 * @param intent Intent对象 */ @Override public void OnKxActivityResult(int requestCode, int resultCode, Intent intent) { } /** * SDK中自带的onActivityResult方法,接收到返回后调用OnKxActivityResult方法 * @param requestCode 访问代码 * @param resultCode 返回代码 * @param data Intent对象 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); OnKxActivityResult(requestCode,resultCode,data); } /** * 设置是否显示log信息 * @param isDebug 是否显示debug数据 */ @Override public void setIsDebug(boolean isDebug) { this.isDebug = isDebug; MyLog.configAllowLog = isDebug; } /** * 关闭整个应用程序 */ @Override public void finishApp(){ KxActivityStack.getAppManager().AppExit(getApplicationContext()); } }
好了。。干货发送完毕,这是一个雏形,以后我会持续完善,争取打造出一个比较强大的Android快速开发框架。不喜勿喷,有错误还请指正,大家都是在开发道路上打拼的兄弟姐妹,还是那句话,希望能帮助到一些热爱Android的朋友。。谢谢,思密达!
下次更新我会将这套代码放上jcenter和github上去。。这样就可以省去童鞋们copy来copy去了。。
相关文章推荐
- Android App框架设计之编写基类BaseActivity
- Android App框架设计之编写基类BaseActivity
- Android App框架设计 基类BaseActivity
- android app 框架之BaseActivity
- app只有一个activity的ui框架设计猜想
- android应用框架设计之Activity管理类:AppManager
- AppCompatActivity与toolbar的结合,封装BaseActivity
- 上门洗车APP --- Android客户端开发 之 网络框架封装介绍(二)
- Android快速开发框架Android_BaseLib,集成了常用工具类,自定义View控件,Base基类封装,常用开源框架
- Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(一)
- Android AndBase框架内部封装实现进度框、Toast框、弹出框、确认框(二)
- 上门洗车APP --- Android客户端开发 之 网络框架封装介绍(一)
- android应用框架搭建------BaseActivity
- android应用框架搭建之BaseActivity
- Android实战:手把手实现“捧腹网”APP(二)-----捧腹APP原型设计、实现框架选取
- Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(二)
- Android中基类BaseActivity的设计与实现
- Android软硬整合设计与框架揭秘: HAL&Framework &Native Service &App&Browser架构设计与实战开发
- Android 学习笔记之AndBase框架学习(二) 使用封装好的进度框,Toast框,弹出框,确认框...
- Android 学习笔记之AndBase框架学习(三) 使用封装好的函数完成Http请求..