如何保证Activity实例个数唯一(Activity启动模式)

如何保证Activity实例个数唯一(Activity启动模式),第1张

public class ActA extends Activity { / Called when the activity is first created / @Override public void onCreate(Bundle savedInstanceState) { superonCreate(savedInstanceState); TextView textView = new TextView(this); / standard 模式: <p> 当使用当前代码块启动Activity时,每次都是新创建了一个Activity实例 因为是使用默认启动模式(标准模式),我们可以通过下面TextView文本中 hash code 来识别是否为新Activity 此时点击back可以依次看到先前启动的Activity实例,类似栈退出 *** 作,而启动过程类似压栈 *** 作 singleTop 模式: <p> 运行的时候会发现,按多少遍按钮,都是相同的ActiA实例,因为该实例在栈顶,因此不会创建新的实例如果回退,将退出应用 singleTop模式,可用来解决栈顶多个重复相同的Activity的问题如果是A Activity跳转到B Activity,再跳转到 A Activity,行为就和standard一样了,会在B Activity跳转到A Activity的时候创建A Activity的新实例,因为当时的 栈顶不是A Activity实例 singleTask 模式: <p> 当intent到来,需要创建singleTask模式Activity的时候,系统会检查栈里面是否已经有该Activity的实例 如果有直接将 intent发送给它 singleInstance模式: <p> 首先要说一下Task的概念如果是Swing或者Windows程序,可能有多个窗口可以切换,但是你无法在自己程序中复用人家的窗口 注意是直接复用人家的二进制代码,不是你拿到人家api后的源代码级调用Android可以做到,让别人的程序直接复用你的 Activity(类似桌面程序的窗口)Android为提供这种机制,就引入了Task的概念 <p> Task可以认为是一个栈,可放入多个Activity比如启动一个应用,那么Android就创建了一个Task, 然后启动这个应用的入口Activity ,就是intent-filter中配置为main和launch的那个(见一个APK文件部署产生多个应用安装 的效果)这个Activity是根 (Root)Activity,可能会在它的界面调用其他Activity,这些Activity如果按照上面那三个模式 ,也会在这个栈(Task)中,只是实例化的策略不同而已 验证的办法是调用和打印Activity的taskId: <p> TextView textView2 = new TextView(this); textView2setText("task id: "+thisgetTaskId()); 会发现,无论切换Activity,taskId是相同的 当然也可以在这个单一的Task栈中,放入别人的Activity,比如google地图,这样用户看过地图按回退键的时候, 会退栈回到调用地图的Activity对用户来说,并不觉得在 *** 作多个应用这就是Task的作用 但是,有这样的需求,多个Task共享一个Activity(singleTask是在一个task中共享一个Activity) 现成的例子是google地图比如我有一个应用是导游方面的,其中调用的google地图Activity那么现在我比如按home键, 然后到应用列表中打开google地图,你会发现显示的就是刚才的地图,实际上是同一个Activity 如果使用上面三种模式,是无法实现这个需求的google地图应用中有多个上下文Activity,比如路线查询等的, 导游应用也有一些上下文Activity在各自应用中回退要回退到各自的上下文Activity中 singleInstance模式解决了这个问题(绕了这么半天才说到正题),让这个模式下的Activity单独在一个task栈中 这个栈只有一个Activity导游应用和google地图应用发送的intent都由这个Activity接收和展示 这里又有两个问题: <p> 如果是这种情况,多个task栈也可以看作一个应用比如导游应用启动地图Activity, 实际上是在导游应用task栈之上singleInstance模式创建的 (如果还没有的话,如果有就是直接显示它)一个新栈,当这个栈里面的唯一Activity ,地图Activity回退的时候,只是把这个栈移开了, 这样就看到导游应用刚才的Activity了;多个应用(Task)共享一个Activity要求这些应用都没有退出 ,比如刚才强调要用home键从导游应用切换到地图应用因为,如果退出导游应用 而这时地图应用也并未运行的话,那个单独的地图Activity(task)也会退出了 如果还是拿刚才的ActA和ActB的示例,可以把ActB的模式改为singleInstance,ActA为standard,进行一下测试 / textViewsetText("Activity id:" + this + "task Id:" + thisgetTaskId()); Button button = new Button(this); buttonsetText("go ActB"); buttonsetOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intentsetClass(ActAthis, ActBclass); startActivity(intent); } }); LinearLayout layout = new LinearLayout(this); layoutsetOrientation(LinearLayoutVERTICAL); layoutaddView(textView); layoutaddView(button); thissetContentView(layout); } } ActBjava文件:

public class ActB extends Activity { / Called when the activity is first created / @Override public void onCreate(Bundle savedInstanceState) { superonCreate(savedInstanceState); TextView textView = new TextView(this); textViewsetText("Activity id:" + this + "task Id:" + thisgetTaskId()); Button button = new Button(this); buttonsetText("go actA"); buttonsetOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intentsetClass(ActBthis, ActAclass); startActivity(intent); } }); LinearLayout layout = new LinearLayout(this); layoutsetOrientation(LinearLayoutVERTICAL); layoutaddView(textView); layoutaddView(button); thissetContentView(layout); } protected void onDestory(){ superonDestroy(); Systemoutprintln("____B ondestory_____"); } } AndroidMenifestxml文件(配置启动模式):

<

DEVICE_ID

这是Android系统为开发者提供的用于标识手机设备的串号,也是各种方法中普适性较高的,可以说几乎所有的设备都可以返回这个串号,并且唯一性良好。

这个DEVICE_ID可以同通过下面的方法获取:

TelephonyManager tm = (TelephonyManager)getSystemService(ContextTELEPHONY_SERVICE); String DEVICE_ID = tmgetDeviceId();

它会根据不同的手机设备返回IMEI,MEID或者ESN码,但在使用的过程中有以下问题:

非手机设备:最开始搭载Android系统都手机设备,而现在也出现了非手机设备:如平板电脑、电子书、电视、音乐播放器等。这些设备没有通话的硬件功能,系统中也就没有TELEPHONY_SERVICE,自然也就无法通过上面的方法获得DEVICE_ID。

权限问题:获取DEVICE_ID需要READ_PHONE_STATE权限,如果只是为了获取DEVICE_ID而没有用到其他的通话功能,申请这个权限一来大才小用,二来部分用户会怀疑软件的安全性。

厂商定制系统中的Bug:少数手机设备上,由于该实现有漏洞,会返回垃圾,如:zeros或者asterisks

MAC ADDRESS

可以使用手机Wifi或蓝牙的MAC地址作为设备标识,但是并不推荐这么做,原因有以下两点:

硬件限制:并不是所有的设备都有Wifi和蓝牙硬件,硬件不存在自然也就得不到这一信息。

获取的限制:如果Wifi没有打开过,是无法获取其Mac地址的;而蓝牙是只有在打开的时候才能获取到其Mac地址。

获取Wifi Mac地址:

获取蓝牙 Mac地址:

Sim Serial Number

装有SIM卡的设备,可以通过下面的方法获取到Sim Serial Number:

TelephonyManager tm = (TelephonyManager)getSystemService(ContextTELEPHONY_SERVICE); String SimSerialNumber = tmgetSimSerialNumber();

注意:对于CDMA设备,返回的是一个空值!

ANDROID_ID

在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID,当设备被wipe后该值会被重置。可以通过下面的方法获取:

import androidproviderSettings; String ANDROID_ID = SettingsSystemgetString(getContentResolver(), SettingsSystemANDROID_ID);

ANDROID_ID可以作为设备标识,但需要注意:

厂商定制系统的Bug:不同的设备可能会产生相同的ANDROID_ID:9774d56d682e549c。

厂商定制系统的Bug:有些设备返回的值为null。

设备差异:对于CDMA设备,ANDROID_ID和TelephonyManagergetDeviceId() 返回相同的值。

Serial Number

Android系统23版本以上可以通过下面的方法得到Serial Number,且非手机设备也可以通过该接口获取。

String SerialNumber = androidosBuildSERIAL;

使用DataFrame中的drop_duplicates方法,可以删除“重复值”,返回字段的“唯一值”

实现代码:数据框名drop_duplicates(["字段名"])

备注:通过 数据框名drop_duplicates(["字段名"])shape[0],可以获取“唯一值”的个数。

实例化对象是指是指用这个类来定义一个具体的事物

如何确保它的实例化对象只得一个?

可以通过使用静态变量的办法在类中加一个静态变量,然后在类的构造函数中做一下判断就好了

class

a

{

a()

{

static

a=0;

if(a==0)

{

初始化对象;

}

else

{

不能初始化对象,当前内存中多于一个些类的对象;

}

}

};

可以从两方面理解:

首先,类的静态成员变量就是指的类共享的对象,而单例模式的对象设成静态就是为了让该类所有成员共享同一个对象,所以从语义上是合适的;

其次,从语法考虑,常见的单例模式都是通过一个静态方法(如getInstance)返回其单例,因为静态方法的内部不能直接使用非静态变量,所以返回的这个实例就是静态的。

其实,学模式不用钻牛角尖,你试试,写成非静态的,总有办法破坏你的单例。

以上就是关于如何保证Activity实例个数唯一(Activity启动模式)全部的内容,包括:如何保证Activity实例个数唯一(Activity启动模式)、如何获取Android设备唯一识别码、python中dataframe怎么获取字段唯一值列表等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9687203.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存