Android SDK开发 — TitleBar重构 – 使用策略模式、舍弃代理模式

最后更新于:2022-04-01 10:06:08

代理模式  之前的使用如下。Activity和Fragment同时implement AppTitle ~~~ public abstract class BaseActivity extends Activity implements Handler.Callback, AppTitle { ~~~ ~~~ public class BaseFragment extends Fragment implements AppTitle ~~~ 修改后的 ~~~ public class BaseFragment extends Fragment { private AppTitle appTitle; @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Log.d("fragment:onCreateView", getView()); // appTitle = new TitleMgr(getActivity(), getView()); appTitle.initTitle(); } public AppTitle getAppTitle() { return appTitle; } public void setAppTitle(AppTitle appTitle) { this.appTitle = appTitle; } ~~~ 采用策略模式 如果某个BaseFragment的样式不太一样,可以重新AppTitle模块。同时又不影响整体app的使用。 默认的实现类是TitleMgr
';

android SDK核心功能 — 消息传递与界面刷新

最后更新于:2022-04-01 10:06:05

今天来分享一下 项目中view刷新相关的核心功能。 android里线程之间消息的传递都是借助Handler来实现的 用到的场景主要是是Activity、Fragment、Application 、Service、Thread之间的消息互相传递 此实现必须借助抽象类来实现即 BaseActivity  BaseFragment PhoebeApp (现在不讨论Service之间的消息传递) 先来看一下BaseActivity的实现 ~~~ public abstract class BaseActivity extends Activity implements Handler.Callback{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMgr.push(this); findViewById(); } @Override public boolean handleMessage(Message msg) { return false; } @Override protected void onDestroy() { super.onDestroy(); ActivityMgr.remove(this); } } ~~~ 其中BaseFragment的实现类似。省略 接下来看一下核心类 ~~~ /** * app中用于UI/非UI线程通信的核心工具类<br> * 可以再"UI/非UI线程"往"UI线程"中发信息, 最终接收方为 {@link BaseActivity} {@link BaseFragment} {@link PhoebeApp} * * @author coffee<br> * 2015-12-26下午4:36:26 */ public class HandlerMgr { public static void sendMessage(int what) { int delayMillis = 0; final Message msg = Message.obtain(); msg.what = what; sendMessage(msg, delayMillis); } /** * 将消息发往Application、Activity、Fragment * * @param orig * @param delayMillis */ public static void sendMessage(Message orig, int delayMillis) { // 发往application Message appMessage = Message.obtain(orig); PhoebeApp.getHandler().sendMessage(appMessage); // 发往Activity ArrayList<?> activities = ActivityMgr.getAllActivities(); for (final Object activity : activities) { boolean result = handle(activity, orig, delayMillis); if (result == true) { break;// 停止继续分发该Message } else { continue; } } // 发往Fragment // ArrayList<?> fragments = FragmentMgr.getAllFragments(); // for (final Object fragment : fragments) { // boolean result = handle(fragment, orig, delayMillis); // if (result == true) { // break;// 停止继续分发该Message // } else { // continue; // } // } } <span style="white-space:pre"> </span> private static boolean handle(final Object activityOrFragment, Message orig, int delayMillis) { final Message msg = Message.obtain(orig); if (delayMillis == 0) { boolean result = false; if (activityOrFragment instanceof Handler.Callback) { ((Handler.Callback) activityOrFragment).handleMessage(msg); } return result; } else { PhoebeApp.getHandler().postDelayed(new Runnable() { @Override public void run() { if (activityOrFragment instanceof Handler.Callback) { ((Handler.Callback) activityOrFragment).handleMessage(msg); } } }, delayMillis); } return false; } } ~~~ 如果Thread发送的http请求 。请求完成以后 ~~~ public void run(){ // ...处理网络请求 Message msg = Message.obtain(); msg.what = 123; msg.obj = "{json字符串}"; HandlerMgr.sendMessage(msg, 0); } ~~~ 这个时候如果你Activity需要接收返回的结果 ~~~ @Override public boolean handleMessage(Message msg) { switch (msg.what) { case 123: String json = msg.obj + ""; //处理json数据 break; } } ~~~ 如果你想在多个Activity处理该http返回的结果。只需要在Activity的handleMessage中加一个case就行了 如果需要在多个Activity中接收,这里需要注意一下handlerMessage的返回值 如果返回true 只会有一个Activity 接收到。剩下的都接收不到了。 ~~~ for (final Object activity : activities) { boolean result = handle(activity, orig, delayMillis); if (result == true) { break;// 停止继续分发该Message } else { continue; } } ~~~
';

Android SDK开发 — TitleBar重构 (代理模式-优化)

最后更新于:2022-04-01 10:06:03

上一篇讲到 [](http://blog.csdn.net/id19870510/article/details/50397129)[Android SDK开发 -- TitleBar重构 (代理模式的使用](http://blog.csdn.net/id19870510/article/details/50397129)[)](http://blog.csdn.net/id19870510/article/details/50397129) 然后补了一下代理设计模式。参考书籍《大话设计模式》 改善一下之前的代码设计。 先来定义一个接口 ~~~ /** * AppTitle接口 * * @author coffee <br> * 2016-1-2 下午10:17:53 */ public interface AppTitle { /** * 初始化Title view */ public void initTitle(); /** * 设置app的title * * @param leftTitle * @param middleTitle * @param rightTitle */ public void setTitle(TitleRes leftTitle, TitleRes middleTitle, TitleRes rightTitle); } ~~~ 接口的实现 ~~~ public class TitleMgr implements AppTitle { ~~~ TitleMgr的实现参考上一篇文章 然后改善一下BaseActivity的类(该类相当于AppTitle的代理类,TitleMgr是AppTitle的实现类) ~~~ public abstract class BaseActivity extends Activity implements Handler.Callback, AppTitle { private AppTitle appTitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); <span style="white-space:pre"> </span>//.... findViewById(); } /** * 初始化title View */ protected void findViewById() { initTitle(); } @Override public void initTitle() { appTitle = new TitleMgr(getContext(), findViewById(android.R.id.content)); appTitle.initTitle(); } /** * 设置app的title栏 * * @param leftTitle * @param middleTitle * @param rightTitle */ @Override public void setTitle(TitleRes leftTitle, TitleRes middleTitle, TitleRes rightTitle) { appTitle.setTitle(leftTitle, middleTitle, rightTitle); } ~~~ BaseFragment的实现省略。。与Activity类似 至于为什么要定义一个接口AppTitle,而不是直接拿实现类TitleMgr来用。。 目前表示不是很理解。  网上所有的示例都采用接口来实现。。。。。。大概是为了统一代理类和实现类的操作吧。。
';

Android SDK开发 — TitleBar重构 (代理模式的使用)

最后更新于:2022-04-01 10:06:01

BaseFragment的TitleBar封装如下 ~~~ public class BaseFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d("fragment:onCreateView", getView()); return null; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Log.d("fragment:onCreateView", getView()); findViewById(); } private ViewSwitcher[] titleSwitcher; /** * 初始化View */ protected void findViewById() { titleSwitcher = new ViewSwitcher[3]; titleSwitcher[0] = (ViewSwitcher) findViewById(R.id.app_title_left_switcher); titleSwitcher[1] = (ViewSwitcher) findViewById(R.id.app_title_middle_switcher); titleSwitcher[2] = (ViewSwitcher) findViewById(R.id.app_title_right_switcher); } protected void setTitle(TitleRes leftTitle, TitleRes middleTitle, TitleRes rightTitle) { TitleRes[] reses = new TitleRes[] { leftTitle, middleTitle, rightTitle }; for (int i = 0; i < reses.length; i++) { TitleRes res = reses[i]; ViewSwitcher switcher = titleSwitcher[i]; if (res == null) { switcher.setVisibility(View.INVISIBLE); } else { switcher.setVisibility(View.VISIBLE); // 触发单击事件的View View clickView = null; // 文字 if (res.getType() == 0) { switcher.setDisplayedChild(0);// 显示TextView // Object resource = res.getResource(); String title = resource instanceof Integer ? getResources().getString((Integer) resource) : String.valueOf(resource); ((TextView) switcher.getChildAt(0)).setText(title); clickView = switcher.getChildAt(0); } else { switcher.setDisplayedChild(1);// 显示ImageView // int imageResource = (Integer) res.getResource(); ((ImageView) switcher.getChildAt(1)).setImageResource(imageResource); clickView = switcher.getChildAt(1); } // 设置title的单击事件 clickView.setOnClickListener(res.getClickListener()); } } } protected View findViewById(int id) { return getView().findViewById(id); } } ~~~ 子类调用 ~~~ public class HomeFragment extends BaseFragment implements View.OnClickListener { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View layout = inflater.inflate(R.layout.home, container, false); super.onCreateView(inflater, container, savedInstanceState); return layout; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); findViewById(R.id.home_title_sample).setOnClickListener(this); TitleRes left = null; TitleRes middle = new TitleRes("首页标题"); TitleRes right = null; setTitle(left, middle, right); } ~~~ 可以发现跟BaseActivity 中的代码实现基本上是类似的 但是BaseActivity和BaseFragment又没有共同的父类  这个时候需要采用 组合的方式进行代码重构 ~~~ /** * 因为Fragment和Activity没有共同的父类 ,但是他们各自的父类里又有一些TitleBar相同的业务逻辑处理<br> * 所以我创建了该类 * * @author coffee <br> * 2015-12-24 下午10:26:10 */ public class TitleMgr { /** * TitleBar的上下文 */ private Context context; /** * TitleBar所在的顶层View容易 */ private View contentView; /** * 三个Title */ private ViewSwitcher[] titleSwitcher; public TitleMgr(Context context, View contenView) { this.context = context; this.contentView = contenView; } private Resources getResources() { return context.getResources(); } private View findViewById(int id) { return contentView.findViewById(id); } /** * 初始化title bar */ public void findViewById() { titleSwitcher = new ViewSwitcher[3]; titleSwitcher[0] = (ViewSwitcher) findViewById(R.id.app_title_left_switcher); titleSwitcher[1] = (ViewSwitcher) findViewById(R.id.app_title_middle_switcher); titleSwitcher[2] = (ViewSwitcher) findViewById(R.id.app_title_right_switcher); } public void setTitle(TitleRes leftTitle, TitleRes middleTitle, TitleRes rightTitle) { TitleRes[] reses = new TitleRes[] { leftTitle, middleTitle, rightTitle }; for (int i = 0; i < reses.length; i++) { TitleRes res = reses[i]; ViewSwitcher switcher = titleSwitcher[i]; if (res == null) { switcher.setVisibility(View.INVISIBLE); } else { switcher.setVisibility(View.VISIBLE); // 触发单击事件的View View clickView = null; // 文字 if (res.getType() == 0) { switcher.setDisplayedChild(0);// 显示TextView // Object resource = res.getResource(); String title = resource instanceof Integer ? getResources().getString((Integer) resource) : String.valueOf(resource); ((TextView) switcher.getChildAt(0)).setText(title); clickView = switcher.getChildAt(0); } else { switcher.setDisplayedChild(1);// 显示ImageView // int imageResource = (Integer) res.getResource(); ((ImageView) switcher.getChildAt(1)).setImageResource(imageResource); clickView = switcher.getChildAt(1); } // 设置title的单击事件 clickView.setOnClickListener(res.getClickListener()); } } } } ~~~ ~~~ public class BaseFragment extends Fragment { private TitleMgr titleMgr; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d("fragment:onCreateView", getView()); return null; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Log.d("fragment:onCreateView", getView()); // titleMgr = new TitleMgr(getActivity(), getView()); titleMgr.findViewById(); } protected void setTitle(TitleRes leftTitle, TitleRes middleTitle, TitleRes rightTitle) { titleMgr.setTitle(leftTitle, middleTitle, rightTitle); } ~~~ ~~~ public abstract class BaseActivity extends Activity { private TitleMgr titleMgr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMgr.push(this); findViewById(); } /** * 初始化View */ protected void findViewById() { titleMgr = new TitleMgr(getContext(), findViewById(android.R.id.content)); titleMgr.findViewById(); } protected void setTitle(TitleRes leftTitle, TitleRes middleTitle, TitleRes rightTitle) { titleMgr.setTitle(leftTitle, middleTitle, rightTitle); } ~~~ 我把业务逻辑抽出来放在单独写好的TitleMgr类中,然后BaseActivity和BaseFragment采用组合?也算是代理模式实现吧
';

android SDK开发 — TitleBar封装(二)

最后更新于:2022-04-01 10:05:59

android SDK开发 -- TitleBar封装 (一) [点击打开链接](http://blog.csdn.net/id19870510/article/details/50386067) 这一篇讲述一下TitleBar怎么增加交互 BaseActivity 中的逻辑实现 ~~~ private ViewSwitcher[] titleSwitcher; /** * 初始化View */ protected void findViewById() { titleSwitcher = new ViewSwitcher[3]; titleSwitcher[0] = (ViewSwitcher) findViewById(R.id.app_title_left_switcher); titleSwitcher[1] = (ViewSwitcher) findViewById(R.id.app_title_middle_switcher); titleSwitcher[2] = (ViewSwitcher) findViewById(R.id.app_title_right_switcher); } protected void setTitle(TitleRes leftTitle, TitleRes middleTitle, TitleRes rightTitle) { TitleRes[] reses = new TitleRes[] { leftTitle, middleTitle, rightTitle }; for (int i = 0; i < reses.length; i++) { TitleRes res = reses[i]; ViewSwitcher switcher = titleSwitcher[i]; if (res == null) { switcher.setVisibility(View.INVISIBLE); } else { switcher.setVisibility(View.VISIBLE); // 触发单击事件的View View clickView = null; // 文字 if (res.getType() == 0) { switcher.setDisplayedChild(0);// 显示TextView // Object resource = res.getResource(); String title = resource instanceof Integer ? getResources().getString((Integer) resource) : String.valueOf(resource); ((TextView) switcher.getChildAt(0)).setText(title); clickView = switcher.getChildAt(0); } else { switcher.setDisplayedChild(1);// 显示ImageView // int imageResource = (Integer) res.getResource(); ((ImageView) switcher.getChildAt(1)).setImageResource(imageResource); clickView = switcher.getChildAt(1); } // 设置title的单击事件 clickView.setOnClickListener(res.getClickListener()); } } } ~~~ 自雷TitleSampleActivity 调用如下 ~~~ @Override protected void findViewById() { setContentView(R.layout.title_demo); super.findViewById(); // setTitle("返回主页", "这是一个Title", "下一个界面"); TitleRes left = new TitleRes("left", new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(TitleDemoActivity.this, "click left", Toast.LENGTH_SHORT).show(); //showToast("click left"); } }); TitleRes middle = new TitleRes("middle", new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(TitleDemoActivity.this, "click middle", Toast.LENGTH_SHORT).show(); //showToast("click middle"); } }); TitleRes right = new TitleRes("right", new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(TitleDemoActivity.this, "click right", Toast.LENGTH_SHORT).show(); //showToast("click right"); } }); // setTitle(left, middle, right); } ~~~ 这个时候title三个控件都具备了交互的能力   Toast.makeText(TitleDemoActivity.this,"click right",Toast.* LENGTH_SHORT * ).show(); 程序中会频繁的用到 context  Toast等对象 采用Class.this的方式在代码移植、维护、重构等方面很不友好 另外频繁调用Toast每次都那么写的话 麻烦死 所以BaseActivity中新增俩方法 作用于暂且定义为protected  以后估计还得改 ~~~ protected Context getContext() {     returnthis; } ~~~ ~~~ protectedvoid showToast(String message) {     Toast.*makeText*(getContext(), message,Toast.*LENGTH_SHORT*).show(); } ~~~ 这个时候子类调用父类的代码如下 ~~~ TitleRes left =newTitleRes("left",newView.OnClickListener() {     @Override     publicvoid onClick(View v) {         showToast("click left");//     } }); 。。。。中、右略 // setTitle(left,middle, right); ~~~
';

android SDK开发 — TitleBar封装(一)

最后更新于:2022-04-01 10:05:56

假设app的title如下 假设app的title 统一的都是这种左中右结构的 代码如下 ~~~ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/app_title_style" android:baselineAligned="false" android:gravity="center_vertical" android:orientation="horizontal"> <ViewSwitcher android:id="@+id/app_title_left_switcher" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/app_title_left_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="返回"/> <ImageView android:id="@+id/app_title_left_image" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </ViewSwitcher> <ViewSwitcher android:id="@+id/app_title_middle_switcher" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_marginLeft="16dip" android:layout_weight="1"> <TextView android:id="@+id/app_title_middle_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="title"/> <ImageView android:id="@+id/app_title_middle_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> </ViewSwitcher> <ViewSwitcher android:id="@+id/app_title_right_switcher" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/app_title_right_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下一步"/> <ImageView android:id="@+id/app_title_right_image" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </ViewSwitcher> </LinearLayout> ~~~ 先来继续完善一下BaseActivity ~~~ protected void onCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); ActivityMgr.push(this); findViewById(); } // 初始化app中通用的控件 protected void findViewById(){ } // 设置标题栏 protected void setTitle(){ } ~~~ 然后看一下BaseActivity的具体实现类TitleDemoActivity ~~~ public class TitleDemoActivity extendsBaseActivity{ protectedvoid onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); } protectedvoid findViewById(){ setContentView(R.layout.title_demo); super.findViewById(); super.setTitle();// 设置标题栏 } } ~~~ ### TitleBar封装 BaseActivity的设计初衷是所有的Activity的都继承该类。 首先定义一些通用的属性、以及方法 ~~~ private ViewSwitcher mLeftSwitcher; private ViewSwitcher mMiddleSwitcher; private ViewSwitcher mRightSwitcher; /** * 初始化View */ protected void findViewById() { mLeftSwitcher = (ViewSwitcher) findViewById(R.id.app_title_left_switcher); mMiddleSwitcher = (ViewSwitcher) findViewById(R.id.app_title_middle_switcher); mRightSwitcher = (ViewSwitcher) findViewById(R.id.app_title_right_switcher); } protected void setTitle(String left, String middle, String right) { ((TextView) mLeftSwitcher.getChildAt(0)).setText(left); ((TextView) mMiddleSwitcher.getChildAt(0)).setText(middle); ((TextView) mRightSwitcher.getChildAt(0)).setText(right); } ~~~ 子类调用 ~~~ public class TitleDemoActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void findViewById() { setContentView(R.layout.title_demo); super.findViewById(); setTitle("返回主页", "这是一个Title", "下一个界面"); } } ~~~
';

android SDK开发– 功能设计

最后更新于:2022-04-01 10:05:54

# 功能设计 先把app常用的功能进行抽象,主要从Activity Fragment Service等控件进行考虑。 其次完善相关的工具类。主要从代码封装、迭代、可维护性等方面考虑。 ### 抽象 ### Activity的抽象 Activity抽象主要目的是简化具体功能界面的工作量。主要通过代码封装的方式来达到效果。 同时需要处理网络请求、UI刷新等操作 ### Fragment的抽象 Fragment的抽象与activity类似。但不同的是需要处理多个Fragment之间的互相调用,传参方式也不太一样。 ### 工具类 App需要一个管理Activity或者Fragment的工具类,对其做全局的操作(方法调用) 为了减少代码的耦合度。不建议在Activity中直接加static引用。可以通过写一些工具类间接的实现。   Activity中访问网络请求以及回调刷新UI是一件比较繁琐的事儿。常规的做法是new一个Thread是传入一个Handler对象,网络请求完成以后sendMessage刷新。但是这种做法耦合度比较强,而且好多业务逻辑都需要在Activity中处理,代码臃肿   ~~~ private Handler handler; protected void onCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); handler= new handler(){ publicvoid handlerMessage(){ if(msg.what== 1){ //do sth } } } } public class NetRunnable implementsRunnable{ privateHandler handler; publicNetRunnable(Handler handler){ this.handler= handler; } publicvoid run(){ //do sth 处理网络等 Messagemsg = Message.obtain(); msg.what= 1; msg.obj= “网络请求结果”; this.handler.sendMessage(msg); } } ~~~ 建议将网络请求的代码封装一下,  封装后续 ### ActivityMgr 这个类的作用主要是保存app中所有正在运行的Activity的引用。   ~~~ private static Stack<BaseActivity>activities = new Stack<BaseActivity >; public static void push(BaseActivityactivity){ activities.push(activity); } public static void remove(BaseActivityactivity){ activities.remove(activity); } public class BaseActivity extends Activity public void onCreate(BundlesaveInstanceState){ ActivityMgr.push(this); } public void onDestroy(){ ActivityMgr.remove(this); } ~~~ 解析一下为什么onDestroy的时候采用remove方法而不是pop() 防止acitivty AB,   A启动 B  如果此时A#finish调用Stack#pop则会把B的引用移除   Fragment的工具类先略过
';

Android SDK开发 (三) App的属性配置

最后更新于:2022-04-01 10:05:52

# App的属性配置 一般app测试环境和线上环境好多配置都不同,比如说控制日志打印、服务器地址等 所以需要一个类专门进行app的属性配置。 至于为何不在PhoebeApp中写,一是减少PhoebeApp类的代码量,二分开写配置起来更自由。代码更清晰 因为是全局性的配置,所以类中的方法字段全部定义为static ~~~ package phoebe.frame; import phoebe.frame.util.Log; import android.app.Application; /** * 该类主要针对测试以及线上环境的不同而做一些属性配置操作 * * @author coffee <br> * 2015-12-17 下午8:48:18 */ public class PhoebeConfig { /** * 默认开发环境 false表示线上正式环境 */ private static boolean debug = true; /** * app接口服务器地址(线上环境) */ private static String serverUrl; /** * 同上 -- 测试环境 */ private static String serverUrl_test; /** * 初始化进行app的配置 一般在 {@link Application#onCreate()}中配置 */ public static void init() { if (debug) { Log.setOpen(true); } else { Log.setOpen(false); } } /** * 获取接口服务器的地址 * * @return */ public static String getServerUrl() { if (debug) { return serverUrl_test; } else { return serverUrl; } } } ~~~ 定义完成以后 在PhoebeApp的onCreate中调用,使用 ~~~ public class PhoebeApp extends Application { <span style="white-space:pre"> </span> @Override public void onCreate() { super.onCreate(); // 初始化app配置信息 PhoebeConfig.init(); } ~~~ 做完以上工作,开始着手具体的功能设计。
';

Android sdk开发(二) Log日志类的设计

最后更新于:2022-04-01 10:05:50

# Log类的设计 正式代码设计之前我们先考虑一下日志类的使用。 日志主要用在调试app 一些复杂的业务流程,借助log 可以很容易找到问题所在 因为android.util.Log 定义为final类(不可继承) 所以我采用组合的方式才重写一个可以控制开关的日志工具类。考虑到Log应用的广泛性,所以定义为static,生命周期为全局 ~~~ public class Log { /** * 日志的开关, false 表示不打印日志 */ private static boolean open = false; public static boolean isOpen() { return open; } public static void setOpen(boolean open) { Log.open = open; } ~~~ Log的开关控制,一般在app初始化的地方设置。后续再讨论 ~~~ public static void d(String tag, String msg){ if(open == false){ return; // 不打印日志 } android.util.Log.d(tag,msg); } ~~~   其中tag和msg 考虑到传入的参数需要频繁转型 比如说像打印一个int型的变量值。这时候会很不方便。同理其他非String类型的都需要转化为String 。 因为优化一下当前方法 ~~~ public static voidd(Object tag, Object msg){ if(open == false){ return; // 不打印日志 } android.util.Log.d(String.valueOf(tag), String.valueOf(msg)); } ~~~ 这时候如果传入的 tag == null 或者“” 或者 包含有” ” \n\r等字符 ,那么输出的结果可能不是我们想要的, 接着继续优化一下该方法 ~~~ package phoebe.frame.util; /** * 日志打印 * * @author coffee <br> * * 2015-12-16 下午9:39:41 */ public class Log { /** * 日志的开关, false 表示不打印日志 */ private static boolean open = false; public static boolean isOpen() { return open; } public static void setOpen(boolean open) { Log.open = open; } public static void d(Object tag, Object msg) { if (open == false) { return; } tag = handleMsgOrTag(tag); msg = handleMsgOrTag(msg); android.util.Log.d(String.valueOf(tag), String.valueOf(msg)); } private static Object handleMsgOrTag(Object msgOrTag) { if (msgOrTag == null) { msgOrTag = "[null]"; } else if (msgOrTag.toString().trim().length() == 0) { msgOrTag = "[\"\"]"; } else { msgOrTag = msgOrTag.toString().trim(); } return msgOrTag; } } ~~~
';

Android sdk开发(一)Application设计

最后更新于:2022-04-01 10:05:47

# Appllication的功能设计 每一个App都应该有一个扩展的Application。这个类中主要写一些整个app广泛用到的方法或app相关配置操作 application的生命周期是从app启动到退出。进程结束。所以在application中变量都定义为static,  也可以定义为非static。只是调用的时候稍微麻烦点 ~~~ public classPhoebeApp extends android.app.Application        private static Context context;        private static Handler handler; ~~~ App的上下文引用,主要用于调用系统api 比如说 context.getSystemService(String name) 我们在app的方法中调用的时候可以 PhoebeApp.getContext().getSystemService(Context.NOTIFICATION_SREVICE)。 不需要每次使用的时候都传入参数Context,在类设计的时候可以更加自由。   另外App中会频繁用到handler与线程的交互。有时候我们需要用Handler#postDelayed(Runnable r , intdelayMills) 这个时候我们无需重新new handler(); 只需要调用全局的PhoebeApp#getHander() 即可   更高级的用法先不讲。后续再     至此一个基本的Application扩展类已经定义完成 ~~~ package phoebe.frame; import android.app.Application; import android.content.Context; import android.os.Handler; /** * 这个类中主要做一些全局的配置, 或者整个app广泛用到的方法逻辑<br> * * 生命周期从 * * @author coffee<br> * 2015-12-15下午3:28:30 */ public class PhoebeApp extends Application { /** * app的上下文的引用,主要用于调用系统api的时候传参 */ private static Context context; /** * 全局Handler 一般一个app只需要定义一个Handler就搞定了 */ private static Handler handler; @Override public void onCreate() { super.onCreate(); } public static Context getContext() { return context; } public static Handler getHandler() { return handler; } } ~~~
';

Android sdk开发 – 序

最后更新于:2022-04-01 10:05:45

#序 文档是写给自己的。主要目的用来为公司后期的sdk迭代积累经验。相关技术点发布到网上没知会技术总监,  不知道会不会有啥后果。 欢迎对SDK开发感兴趣的朋友阅读。欢迎交流、分享经验。  阅读本文档需要一定的Java开发基础,面向对象的设计思想,以及Java反射、注解等高级应用。另外需要Android开发基础,如果还具备代码重构能力那就更好不过了。  工程源码位于[https://github.com/droidcoffee/Phoebe](https://github.com/droidcoffee/Phoebe) [](https://github.com/droidcoffee/Phoebe) 目录 (一)  Android SDK综合设计 [Application设计](http://blog.csdn.net/id19870510/article/details/50375912) [Log设计](http://blog.csdn.net/id19870510/article/details/50375994) [App的属性配置](http://blog.csdn.net/id19870510/article/details/50376016) (二) Android SDK 功能设计 [Activity / Fragment的抽象](http://blog.csdn.net/id19870510/article/details/50376025)  BaseActivity | BaseFragment TitleBar的设计 一 [TiitleBar封装 ](http://blog.csdn.net/id19870510/article/details/50386067) 二 [TitleBar完善](http://blog.csdn.net/id19870510/article/details/50390460) 三 [TitleBar重构](http://blog.csdn.net/id19870510/article/details/50397129) 四 [TitleBar重构-优化(代理模式的使用)](http://blog.csdn.net/id19870510/article/details/50397129) SDK核心功能  [消息的分发与界面的刷新](http://blog.csdn.net/id19870510/article/details/50482291)
';

前言

最后更新于:2022-04-01 10:05:43

> 原文出处:[android SDK开发](http://blog.csdn.net/column/details/phoebe.html) 作者:[id19870510](http://blog.csdn.net/id19870510) **本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!** # android SDK开发 > android sdk library 开发笔记
';