设计模式解析与实战之单列模式
来源:互联网 发布:美国石油协会api数据 编辑:程序博客网 时间:2024/05/02 01:20
买了大神关爱民与何红辉所著书籍《设计模式解析与实战》,观后有所感、有所悟。
单例模式之饿汉式:
public class Person { /** * 在课堂上不同身份的人说不通的话 */ public void say(){ }}
定义教导主任:
public class Director extends Person { private static final Director mDirector=new Director(); public static Director getDirector(){ return mDirector; } @Override public void say() { super.say(); System.out.println("Director:"+"准备开始上课吧"); }}
定义上课老师:
public class Teacher extends Person { @Override public void say() { super.say(); System.out.println("Teacher:"+"Stand up"); }}
定义上课学生:
public class Student extends Person { @Override public void say() { super.say(); System.out.println("Student:"+"老师好"); }}
定义学校:
import java.util.ArrayList;public class School { private ArrayList<Person> mPersonList=new ArrayList<>(); public void addPerson(Person mPerson){ mPersonList.add(mPerson); } public void showEveryOneSay(){ for(Person mPerson:mPersonList){ mPerson.say(); } }}
下面是测试代码:
public class Test { public static void main(String[] args) { School mSchool =new School(); mSchool.addPerson(new Director()); mSchool.addPerson(new Teacher()); mSchool.addPerson(new Student()); mSchool.addPerson(new Student()); mSchool.showEveryOneSay(); }}
测试输出结果:
单例模式之懒汉式(synchronized 保证单例对象的唯一性):
public class Person { private static Person instance; public Person() { } public static synchronized Person getInstance(){ if(instance==null){ instance=new Person(); } return instance; }}
DCL 实现单例,DCL的闪光点在getInstance方法上,两次判断为空,具体原因想知道更多详情请购买《设计模式解析与实战》自行了解吧,打字麻烦!!当然如果你耐不住性子可以通过以下博客内容找到答案:http://blog.csdn.net/liguangzhenghi/article/details/8076361(个人最喜欢用的方式):
public class Person { private static Person instance; public Person() { } public static Person getInstance(){ if(instance==null){ synchronized (Person.class) { if(instance==null){ instance=new Person(); } } } return instance; } }}
DCL优点:资源利用率高,缺点:第一次加载稍慢(基本可以忽略)。下面是静态内部类单例模式:
public class Person { public Person() { } public static Person getInstance(){ return SingleHolder.instance; } private static class SingleHolder{ private static final Person instance=new Person(); }}
枚举单列(与其他单例模式不同,在反序列时不会重新new ):
public enum PersonEnum { student,teacher,director; public void say(){ }}
通过容器实现单例(下面是对象为例的):
import java.util.HashMap;import java.util.Map;public class PersonManager { private static Map<String ,Object> map=new HashMap<String, Object>(); public PersonManager() { } public static <T> T putPersonService(T t){ map.put(t.getClass().getName(),t); return t; } @SuppressWarnings("unchecked") public static <T> T getPersonService(T t){ t=(T)map.get(t.getClass().getName()); return t; }}
再补充一个特别的单例(Application,每个应用都有一个Application,应用启动就会创建,会调用onCreate方法,此时可以给instance赋值):
import android.app.Application;public class MyApplication extends Application{ public static MyApplication instance; @Override public void onCreate() { super.onCreate(); instance=this; }} <application android:name="com.example.MyApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
在android 源码中的运用例举如下:
WindowManager manager=(WindowManager)getSystemService(Context.WINDOW_SERVICE);
而Context.WINDOW_SERVICE只是在常量类Context里面定义的键:
/** * Use with {@link #getSystemService} to retrieve a * {@link android.view.WindowManager} for accessing the system's window * manager. * * @see #getSystemService * @see android.view.WindowManager */ public static final String WINDOW_SERVICE = "window";
继续跟进Activity..
@Override public Object getSystemService(@ServiceName @NonNull String name) { if (getBaseContext() == null) { throw new IllegalStateException( "System services not available to Activities before onCreate()"); } if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } else if (SEARCH_SERVICE.equals(name)) { ensureSearchManager(); return mSearchManager; } return super.getSystemService(name); }
Activity继承ContextThemeWrapper,这里调用父类getSystemService,继续跟进..
@Override public Object getSystemService(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this); } return mInflater; } return getBaseContext().getSystemService(name);}
不断然而还没看到我想看的,只看到了一个抽象的Context对象,根据何红辉大神说的,我从Activity的ActivityThread入手(Activity的入口是ActivityThread的main函数):
public static void main(String[] args) { ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } // End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
创建ActivityThread后调用attach函数传入参数fasle(非系统应用),会通过Binder机制与ActivityManagerService通信,最终调用performLaunchActivity,然后调用createBaseContextForActivity方法:
private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) { int displayId = Display.DEFAULT_DISPLAY; try { displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token); } catch (RemoteException e) { } ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, displayId, r.overrideConfig); appContext.setOuterContext(activity); Context baseContext = appContext; .....................此处略................... }
上面代码分析到Context实现类ContextImpl,Eclipse开发可能没法继续跟进了,android.jar里面也找不到,这时候需要https://github.com/android这里面去找源码了(framework层),换了Android Studio继续跟踪到了ContextImpl实现类,发现 ServiceManager.getService(key)方法的,没法跟进ServiceManager,只好github上https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/ServiceManager.java继续跟踪:
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.os;import com.android.internal.os.BinderInternal;import android.util.Log;import java.util.HashMap;import java.util.Map;/** @hide */public final class ServiceManager { private static final String TAG = "ServiceManager"; private static IServiceManager sServiceManager; private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>(); private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; } /** * Returns a reference to a service with the given name. * * @param name the name of the service to get * @return a reference to the service, or <code>null</code> if the service doesn't exist */ public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return getIServiceManager().getService(name); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; } /** * Place a new @a service called @a name into the service * manager. * * @param name the name of the new service * @param service the service object */ public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } /** * Place a new @a service called @a name into the service * manager. * * @param name the name of the new service * @param service the service object * @param allowIsolated set to true to allow isolated sandboxed processes * to access this service */ public static void addService(String name, IBinder service, boolean allowIsolated) { try { getIServiceManager().addService(name, service, allowIsolated); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } /** * Retrieve an existing service called @a name from the * service manager. Non-blocking. */ public static IBinder checkService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return getIServiceManager().checkService(name); } } catch (RemoteException e) { Log.e(TAG, "error in checkService", e); return null; } } /** * Return a list of all currently running services. */ public static String[] listServices() throws RemoteException { try { return getIServiceManager().listServices(); } catch (RemoteException e) { Log.e(TAG, "error in listServices", e); return null; } } /** * This is only intended to be called when the process is first being brought * up and bound by the activity manager. There is only one thread in the process * at that time, so no locking is done. * * @param cache the cache of service references * @hide */ public static void initServiceCache(Map<String, IBinder> cache) { if (sCache.size() != 0) { throw new IllegalStateException("setServiceCache may only be called once"); } sCache.putAll(cache); }}
折腾这么久最后还是找到了想要的源码中单例模式的实战,继续拜读大神著作!!
- 设计模式解析与实战之单列模式
- 设计模式之单列
- 设计模式之单列模式
- 设计模式之单列模式
- 设计模式之单列模式
- 设计模式之单列模式
- java设计模式之单列
- 设计模式解析与实战之Builder模式
- 设计模式解析与实战之原型模式
- 设计模式解析与实战之工厂方法模式
- 设计模式解析与实战之策略模式
- 设计模式解析与实战之状态模式
- Android源码设计模式解析与实战之二单例模式
- 设计模式之单列模式(03)
- 设计模式之单列模式:简单实现
- 创建之单列模式设计模式测试
- iOS设计模式之单列模式
- php 设计模式之 单列模式
- netty5源码分析(4)--学习笔记
- Protocol Buffers 安装使用笔记
- RMQ算法分析
- ZZULIOJ 1794 多项式相加
- ueditor 编辑器,自定义图片上传及图片显示
- 设计模式解析与实战之单列模式
- visual studio 开发常用设置
- @class属性
- 对Android log异常分析方法
- zoj 1940 Dungeon Master
- h264 流、帧结构
- Bitmap 的内存优化
- Java通过JNI调用DLL动态库
- 使用CocoaPods更新第三方库出错的解决方法