2014-10-28 16:16:46 u014544193 阅读数 891

在很多设计模式中,我相信大多数程序猿最早接触的设计模式就是单例模式啦,当然了我也不例外。单例模式应用起来应该是所有设计模式中最简单的。单例模式虽然简单,但是如果你去深深探究单例模式,会涉及到很多很多知识,我会继续更新这篇文章的。单例模式在整个系统中就提供了一个对象,然后整个系统都去使用这一个对象,这就是单例的目的。

一、饱汉式单例:

public class Singleton {    
	    /**  
	     * 单例对象实例  
	     */    
	    private static Singleton instance = null;    
	    public static Singleton getInstance() {    
	        if (instance == null) {                     
	            instance = new Singleton();           
	        }    
	        return instance;    
	    }    
	}

二、饿汉式单例:

public class Singleton {    
		    /**  
		     * 单例对象实例  
		     */    
		    private static Singleton instance = new Singleton();    
		     
		   public static Singleton getInstance() {    
		        return instance;    
		    }    
		}

这两种单例在实际的代码中,往往是不能满足要求的,这就需要我们根据自己的需求来改写这些单例模式,

例如:如果创建的单例对象需要其他参数,这个时候,我们就需要这样改写:

public class Singleton {    
		    /**  
		     * 单例对象实例  
		     */    
		    private static Singleton instance = null;    
		     
		   public static Singleton  getInstance(Context context) {  
		        if (instance == null) {  
		        	instance = new Singleton(context);  
		        }  
		    return instance;  
		}
	}

例如:资源共享情况下,必须满足多线程的并发访问,这个时候,我们就应该这么做:

public class Singleton {    
		    /**  
		     * 单例对象实例  
		     */    
		    private static Singleton instance = null;    
		     
		    public synchronized static Singleton getInstance() {    
		        if (instance == null) {    
		            instance = new Singleton();    
		        }    
		        return instance;    
		    }    
	}

其实无论什么条件下,无论怎么改变,都是这两种单例模式的变种!!!!


2016-08-05 15:11:14 gacmy 阅读数 338

单线程单例模式

public class Singleton {

        //定义一个属性,用来保存Singleton类对象的实例
        private static Singleton instance;

        //私有构造器,该类不能被外部类使用new方式实例化
        private Singleton(){

        }

        //外部通过该方法获取Singleton类的唯一实例
        public static Singleton getInstance(){
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

此单例模式为非线程安全的,如果两个线程同时调用getInstance方法,很有可能第一个线程刚进入
if(instance == null){}判断内部但是还没有new出实例,第二线程也进去所以创建多个实例。

java多线程程序,线程执行顺序是不确定的,所以在同时多个线程调用Singleton.getInstance()方法时,
存在创建多个实例的可能,会引起程序执行错误。那我们该如何实现多线程下安全的创建一个唯一的实例呢?
锁,加锁。在线程调用Singleton.getInstance()方法时,判断instance == null ? 是,加锁,
其他线程这时只能等待这个线程释放锁,才能进入临界区。那如何加锁,可以使用synchronized。
  public static Singleton getInstance() {
            //synchronized加锁同步会降低效率,这里先判断是否为空
            //不为空则不需要加锁,提高程序效率
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }

单例模式优点

1 在内存中只有一个对象,节省内存空间。
2 避免频繁的创建销毁对象,可以提高性能。
3 避免对共享资源的多重占用。
4 可以全局访问。

适用场景

1 需要频繁实例化然后销毁的对象。
2 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
3 有状态的工具类对象。
4 频繁访问数据库或文件的对象。
5 以及其他我没用过的所有要求只有一个对象的场景。
下面举个android中数据库的例子
    SQLiteOpenHelper采用单例模式:
    public class SQLHelper extends SQLiteOpenHelper{
    public static String DB_NAME = "note.db";
    public static int VERSION = 1;
    private static SQLHelper instance;

    public static SQLHelper getInstance(Context context){
        if(instance == null){
            instance = new SQLHelper(context.getApplicationContext());
        }
        return instance;
    }

    private SQLHelper(Context context){
        super(context,DB_NAME,null,VERSION);
        //this.context = context;
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        NoteDao.createTable(db);

    }



    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}









public class NoteDao {
    public static String TABLE_NAME = "note";
    public static String COLUMN_DATETIME = "datetime";
    public static String COLUMN_CONTENT = "content";
    public static String COLUMN_ID = "id";
    public static String COLUMN_TAG = "tag";
    public static String NOTE_TABLE_CREATE = "create table if not exists "
            +TABLE_NAME +" ("
            +COLUMN_ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "
            +COLUMN_DATETIME+" TEXT,"
            +COLUMN_CONTENT+" TEXT,"
            +COLUMN_TAG +" TEXT"+")";

      static String[] str_column = {COLUMN_DATETIME,COLUMN_CONTENT,COLUMN_TAG};
      static String[] int_cloumn = {COLUMN_ID};

    public static void createTable(SQLiteDatabase db){
        db.execSQL(NOTE_TABLE_CREATE);
    }
    public static void dropTable(SQLiteDatabase db) {
        String sql = "DROP TABLE " +  "IF EXISTS "  + " note";
        db.execSQL(sql);
    }

    private SQLHelper helper;

    public NoteDao(Context context){
        helper = SQLHelper.getInstance(context);
    }


      //插入数据
    public boolean insertBean(NoteBean bean){
        boolean flag = false;
        SQLiteDatabase database = null;
        long id = -1;
        try{
            database = helper.getWritableDatabase();
            ContentValues values = getContentValues(bean);
            String tableName = TABLE_NAME;
            id = database.insert(tableName,null,values);
            flag = (id !=-1?true:false);
            if(database != null){
                database.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        Log.e("gac","insertbean flag:"+flag);
        return flag;
    }

}


执行插入数据的操作 只需要执行new NoteDao(Context).insertBean方法 可以避免创建过多的SqliteHelper对象
2017-03-19 16:52:54 chengjiamei 阅读数 740

单例模式是应用最广的设计模式之一,在应用这种模式的时候,单例对象的类必须保证只有一个实例存在。许多时候,整个系统只需要拥有一个全局对象,这样有利于协调系统的整体行为。如一个应用中,应该只有ImageLoader实例,这个ImageLoader实例中又包含网络请求、缓存系统、线程池等,很耗资源,因此没有理由让他构造多个实例。这种不能自由构造对象的情况就是使用单例模式的场景。在Android系统中存在很多这种场景,比如最常用的context.getSystemService(),BluetoothAdapter.getDefaultAdapter()等等都是使用的单例模式。下面就列出几种单例模式的构建方式以及各种方式的优缺点。

1.懒汉模式

懒汉模式是申明一个静态变量,并且在用户第一次调用getInstance时进行初始化,懒汉模式实现如下:

public class Singleton {
	private static Singleton sInstance;
	private Singleton(){
	}
	public static synchronized Singleton getInstance(){
		if(sInstance == null){
			sInstance = new Singleton();
		}
		return sIntance;
	}
}


getIntance()方法中添加了synchronized关键字,也就是getInstance是一个同步方法,这就是上面所说的在多线程情况下保证单例对象唯一性的手段。但是这样存在一个问题,即使sInstance已经被初始化,每次调用getInstance都会进行同步,这样会消耗不必要的资源,这也是懒汉单例模式存在的最大问题。懒汉模式的最大优点是单例只有在使用的时候才会被实例化,在一定程度上节约了资源;缺点是第一次加载时需要及时初始化,反应稍慢,最大的问题是每次调用getInstance都进行同步,造成不必要的同步开销。一般不建议使用。

2.Double Check Lock(DCL)实现单例

DCL方式实现单例模式的优点是既能够在需要的时候才初始化单例又能保证线程安全,且单例对象的初始化后调用getInstance不进行同步锁。实现如下:

public class Singleton {
    private static Singleton sInstance;
    private Singleton(){}
    public static Singleton getInstance(){
        if(sInstance == null){
              synchronized(Singleton.class){
			if(sInstance == null){
				sInstance = new Singleton();
			}
		}
        }
	return sInstance;
    }
}

本程序的亮点在于getInstance()方法中对sIntance进行了两次非空判断:第一层主要是为了避免不必要的同步,第二层的判断则是为了在null的情况下创建实例。假设线程A执行到sInstance = new Singleton()的语句,这看起来是原子操作,但并不是,这句代码会被编译成多条汇编指令:给Singleton的实例分配内存,调用Singleton的构造函数,初始化成员字段,将sInstance对象指向分配的内存空间(此时的sInstance已经不是null了)。但是由于Java编译器允许处理器乱序执行,所以上述三个步骤的执行顺序无法得到保证。这就会导致DCL失效,而且这种难以跟踪重现的错误会隐藏很久。在JDK1.5后,只需要将sInstance的定义改成private volatile static Singleton sInstance = null就可以保证sInstance对象每次都是从内存中读取,就可以使用DCL的写法来完成单例模式。当然,volatile或多或少会影响到性能,但考虑到程序的正确性,还是值得的。DCL的优点是资源利用率高,第一次执行getInstance时单例才会被实例化,效率高。缺点是第一次加载时反应稍慢,也由于Java内存模型的原因会偶尔失败。在高并发环境下也有一定的缺陷,虽然发生概率较小。DCL模式是使用最多的单例实现方式,它能够在需要时才实例化单例,并且在绝大多数场景下保证单例对象的唯一性,除非你的代码在并发场景比较复杂或者低于JDK6的情况下使用,否则这种方式一定能够满足要求。

3.静态内部类单例模式

DCL虽然在一定程度上解决了资源消耗、多余的同步、线程安全等问题,但是它还是在某些情况下出现失效的问题。这个问题被才会被称为DCL双锁失效。静态内部类实现代码如下:

public class Singleton{
   	 private Singleton(){}
   	 public static Singleton getInstance(){
       		 return SingletonHolder.sInstance; 
    	}

   	private static class SingletonHolder {
	private static final Singleton sInstance = new Singleton();
	}

}
当第一次加载的时候Singleton类时,并不会初始化sInstance,只有第一次在调用Singleton的getS方法时才会导致sIn被初始化。因此第一次调用get方法会导致虚拟机加载SingletonHolder类,这种方法不但保证能够=线程安全们也能够,也能够保证单例对象的唯一性,同时也延迟了单例的实例化,。

4.枚举单例模式档
Java1.5版本起,单元素枚举实现单例模式成为最佳的方法,实现代码如下

class Resource{
}

public enum SomeThing {
    INSTANCE;
    private Resource instance;
    SomeThing() {
        instance = new Resource();
    }
    public Resource getInstance() {
        return instance;
    }
}

上面的类Resource是我们要应用单例模式的资源,具体可以表现为网络连接,数据库连接,线程池等等。
获取资源的方式很简单,只要 SomeThing.INSTANCE.getInstance() 即可获得所要实例。下面我们来看看单例是如何被保证的:
首先,在枚举中我们明确了构造方法限制为私有,在我们访问枚举实例时会执行构造方法,同时每个枚举实例都是static final类型的,也就表明只能被实例化一次。在调用构造方法时,我们的单例被实例化。
也就是说,因为enum中的实例被保证只会被实例化一次,所以我们的INSTANCE也被保证实例化一次。
可以看到,枚举实现单例还是比较简单的,除此之外我们再来看一下Enum这个类的声明:

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable


可以看到,枚举也提供了序列化机制。某些情况,比如我们要通过网络传输一个数据库连接的句柄,会提供很多帮助。

在上述的几种单例模式中,存在一种情况它们会出现重复创建对象的情况,那就是反序列化。通过序列化可以将一个单例的实例对象写到磁盘,然后再读回来,从而有效的获得一个实例。即使构造函数是私有的,反序列化时依然可以通过特殊的途径去创建类的一个新的实例,相当于调用该类的私有构造函数。反序列化操作提供了一个很特别的钩子函数,类中具有一个私有的、被实例化的方法readResolve,这个方法可以让开发人员控制对象的反序列化。上述几个示例中如果要杜绝对象下被反序列化中重新生成对象,那么需要加入如下方法:

private Object readResolve() throws ObjectStreamException{
    return sInstance;
}

也就是在readResolve()中将sInstance对象返回,而不是默认的重新生成一个新的对象。而对于枚举,并不存在这个问题,因为即使反序列化也不会生成新的实例。

5.使用容器实现单例模式

看看这种实现方式:

public class SingletonManager {
private static Map<String,Object> objMap = new HashMap<String,Object>();
private SingletonManager();
public static viud registerServuce(String key,Object instance){
     if(!objMap.containsKey(key){
         objMao.put(key,instance);
}
} 

public static Object getService(String key){
    return objMap.get(key);
}
}



在程序初始化的时候,将多种单例类型注入到一个统一的管理类中,在使用时根据Key获取对象对应类型的独享,这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体的实现,降低了耦合度。

总结:不管以哪种方式实现单例模式,它们的核心原理都是将构造函数私有化,并且通过静态方法获取一个唯一的实例,在获取这个的过程中必须保证线程安全、防止反序列化导致重新生成实例对象等问题。选择哪种方式取决于项目本身,如是否是复杂的并发环境、JDK版本过低、单例对象的资源消耗等。


2018-07-31 23:38:28 huo108 阅读数 195

概念

单例模式就是整个系统有且只有一个唯一的对象,单例模式思想相对比较简单,但是确保整个系统有且只有一个对象,需要注意几个点:

  • 构造函数必须是private;
  • 通过一个静态方法返回单例类对象;
  • 在多线程下注意单例模式的创建;
  • 确保单例类对象在反系列化时不会重新构建对象;

单例模式从实现角度来分可以分:饿汉式单例和懒汉式单例,先看一下它们的实现:

package com.ailian.designpattern.singletonpattern;

/**
* 饿汉式
*/
public class EagerSingleton {

    private static final EagerSingleton eagerSingleton = new EagerSingleton();

    private EagerSingleton() {
    }   

    public static EagerSingleton newInstance() { 
        return eagerSingleton;    
    }

}
package com.ailian.designpattern.singletonpattern;
/**
* 双重检查锁定
* 懒汉式
*/
public class LazySingleton {

    private static LazySingleton lazySingleton;

    private LazySingleton() {
    }   

    public static LazySingleton newInstance() {
        if (lazySingleton == null) {
            synchronized (LazySingleton.class) {
                if (lazySingleton == null){//双重检查锁定
                lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }

}

从上面单例模式的两种方式可以看出
- 饿汉式式在类加载的时候就初始化了对象,所有要提醒占用系统的资源,而懒汉式是在使用对象的时候进行初始化;
- 我们同时发现懒汉式,使用了synchronized两次lazySingleton == null判断,这时防止在多线程调用过程中有可能产生多个
LazySingleton对象:
1、synchronized同步锁,防止不同线程同时调用new方法创建实例;

2、两次lazySingleton == null判断,想象一下,如果没有第一次的lazySingleton == null判断,则每次调用newInstance都会判断同步锁,消耗性能;而如果没有第二次lazySingleton == null判断,则依然有可能出现多个实例被创建,只要两个线程同时判断出第一次的lazySingleton == null为true,则会出现多个对象被创建;

Android源码中单例模式的运用

我们先看这样段代码

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

WindowManager是Framework层的管理类是全局唯一的,显然它使用到就是单例模式,像这样的管理类Android系统的还有很多比如:ActivityManager、PackageManager、TelephonyManager、NotificationManager、WindowManagerService等等,我们这边通过分析WindowManager来分析系统是如何使用的。

getSystemService的方法是Context中定义的:

public abstract class Context{
    //省略其他抽象方法的定义
    public abstract  java.lang.Object getSystemService(java.lang.String name);

}

Context只是定义了一个抽象方法,它的实现是ContextImpl中

/**
* Common implementation of Context API, which provides the base
* context object for Activity and other application components.
*/
class ContextImpl extends Context {
    @Override
    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name);
    }
}

ContextImpl是通过SystemServiceRegistry这个对象获取到的我们在来看看SystemServiceRegistry中getSystemService的实现:

final class SystemServiceRegistry {
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>();

    /**
    * Gets a system service from a given context. 
    */
    public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
    }
}

看到这里就有意思了,这里有一个ServiceFetcher,这个是SystemServiceRegistry的一个内部类,看看它的源码定义:

/**
* Base interface for classes that fetch services.
* These objects must only be created during static initialization.
*/
static abstract interface ServiceFetcher<T> {
    T getService(ContextImpl ctx);
}


/**
* Override this class when the system service constructor needs a
* ContextImpl and should be cached and retained by that context.
*/
static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
    private final int mCacheIndex;
    public CachedServiceFetcher() {
        mCacheIndex = sServiceCacheSize++;
    }
    @Override
    @SuppressWarnings("unchecked")
    public final T getService(ContextImpl ctx) {
        final Object[] cache = ctx.mServiceCache;
        synchronized (cache) {
            // Fetch or create the service.
            Object service = cache[mCacheIndex];
            if (service == null) {
            try {
                service = createService(ctx);
                cache[mCacheIndex] = service;
                } catch (ServiceNotFoundException e) {
                    onServiceNotFound(e);
                }
            }
            return (T)service;
        }
    }
    public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;

}

到这里一切都水落石出了,首先getService方法会从cache中获取,如果获取不到则会调用createService(ctx)创建一个实例,最终返回唯一的实例对象,为了解决多线程中有可能有多个实例被创建,这里使用了synchronized,跟我们上面讲的懒汉式单例模式是一致的;

到这里WindowManager的单例模式获取过程就分析完了,但是呢,我们看看上面的createService方法是个抽象方法,我们并没有看到它的具体实现啊,我们来继续分析,既然ServiceFetcher是从SystemServiceRegistry的一个HashMap静态常量SYSTEM_SERVICE_FETCHERS中获取的,那我们一步一步看这个常量是何时如何添加进去的

final class SystemServiceRegistry {
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>();

    /**
    * Statically registers a system service with the context.
    * This method must be called during static initialization only.
    */
    private static <T> void registerService(String serviceName, Class<T> serviceClass,        ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }
}

同样是在SystemServiceRegistry这个类中有一个registerService方法,对SYSTEM_SERVICE_FETCHERS注册HashMap键值对,截个图来粗略的看一下这个registerService被调用的数量
image
从上图可以看到总共有87个调用,其中我们也找到了我们的WindowManager注册过程

final class SystemServiceRegistry {
    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>();

    registerService(Context.WINDOW_SERVICE, WindowManager.class,
        new CachedServiceFetcher<WindowManager>() {
        @Override
        public WindowManager createService(ContextImpl ctx) {
            return new WindowManagerImpl(ctx);
        }});    
    }
}

在这里我们终于看到了createService的具体实现,这里就是WindowManager的创建方式,最终重建的是WindowManager的一个实现类WindowManagerImpl(cts);

我们再来总结一下整个过程:
- 通过Context调用getSystemService方法时,其实调用的是ContextImpl的getSystemService方法;
- ContextImpl的getSystemService方法会调用SystemServiceRegistry的getSystemService(this, name)方法;
- SystemServiceRegistry的getSystemService(this, name)方法会先从一个静态HashMap先获取ServiceFetcher;
- 在获取ServiceFetcher后去获取WindowManager,如果获取不到则创建一个WindowManager;

单例模式的适用场景

  • 需要频繁的进行创建和销毁的对象;
  • 创建对象时耗时过多或者耗费内存资源过多,而且经常使用的对象;
  • 工具管理类对象;
  • 频繁访问数据库或者文件的对象;

单例模式的优缺点

优点:
- 减少内存消耗,使用单例模式就是为了减少实例的创建,而每创建一个实例都意味者内存的消耗、性能的开销;
- 单例模式可以避免对资源的重复占用,比如对一个文件的操作,如果使用了单例模式,则说明每次只有一个实例对其进行读写操作,避免了对同一个文件的同时读写操作;

缺点:
- 单例模式不符合面向对象的开闭原则,因为如果需要扩展则必须在当前对象中进行修改;
- 容易发生内存泄漏,因为单例对象持有对Context的引用,所有我们传递Context给单例对象时最好使用ApplicationContext;

2014-04-30 18:32:32 q626779313 阅读数 609

在做一个安卓小程序时,想实现”再按一次退出“的效果,主要是要覆写Activity的onKeyDown方法,判断两次按退出键的时间间隔,当大于某个值时,退出程序。


如果当前的Activity栈中只有一个Activity,则只需要调用finish方法结束这个Activity就行,比如登录页面一般是应该程序的第一个Activity,当在登录页面想实现“再按一次退出”的效果时,只需要在判断完时间后,调用finish方法,如下所示:


@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){  
            if((System.currentTimeMillis()-exitTime) > 2000){  
                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();                                
                exitTime = System.currentTimeMillis();   
            } else {
            	finish();
            }
            return true;   
        }
        return super.onKeyDown(keyCode, event);
    }

但如果Activity栈中有多个Activity,在结束掉栈顶Activity后,新的栈顶Activity会成为当前的显示页面,程序并没有实现退出的效果,上网找了很多解决办法,如在finish方法后调用System.exit(0);或者杀死进程android.os.Process.killProcess(android.os.Process.myPid());或者自己建立一个管理Activity 的列表;前两个办法试了下不起作用,第三个方法感觉太麻烦没试。


最后联想到最近在软件体系结构学的单例模式,觉得可以用得上,就试了下,成功解决了这个问题。


每次打开一个App,都只有一个App对象,所以单例指的是当前的应用程序

package com.example.lbspractice;

import android.app.Application;

public class MyApplication extends Application{
	
	// 程序退出标记 
	private static boolean isProgramExit = false; 
	private static MyApplication instance;
	
	public MyApplication(){
		
	}
	
	public static MyApplication getInstance(){
		if(instance==null)
			instance = new MyApplication();
		return instance;
	}
	
	public void setExit(boolean exit) { 
		isProgramExit = exit; 
	} 
	 
	public boolean isExit() { 
		return isProgramExit; 
	} 

}



退出的时候设置MyApplication的退出属性

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){  
            if((System.currentTimeMillis()-exitTime) > 2000){  
                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();                                
                exitTime = System.currentTimeMillis();   
            } else {
            	MyApplication mApp = MyApplication.getInstance(); 
            	mApp.setExit(true); 
            	finish();
            }
            return true;   
        }
        return super.onKeyDown(keyCode, event);
    }

在结束这个Activity后,覆写当前Activity栈中剩余的Activity的onStart方法

@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		MyApplication mApp = MyApplication.getInstance();
		if (mApp.isExit()) { 
			mApp.setExit(false);
			finish(); 
		} 
	}


要注意的是在调用最后一个Activity的finish方法之前要重新把MyApplication的isProgramExit属性设为false,不然在没有清除缓存的情况下,应用程序无法再次开启。


Android单例模式

阅读数 265

Android单例模式简单介绍

博文 来自: u010870167
没有更多推荐了,返回首页