随笔 - 33, 文章 - 0, 评论 - 12, 引用 - 0
数据加载中……

2015年6月23日

Activity四种启动模式

Activity启动方式有四种,分别是:

standard
singleTop
singleTask
singleInstance

可以根据实际的需求为Activity设置对应的启动模式,从而可以避免创建大量重复的Activity等问题。

设置Activity的启动模式,只需要在AndroidManifest.xml里对应的<activity>标签设置android:launchMode属性,例如:

  1. <activity  
  2.     android:name=".A1"  
  3.     android:launchMode="standard" />  

下面是这四种模式的作用:

standard
默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。

例如:
若我有一个Activity名为A1, 上面有一个按钮可跳转到A1。那么如果我点击按钮,便会新启一个Activity A1叠在刚才的A1之上,再点击,又会再新启一个在它之上……
点back键会依照栈顺序依次退出。

singleTop
可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。

例如:
若我有两个Activity名为B1,B2,两个Activity内容功能完全相同,都有两个按钮可以跳到B1或者B2,唯一不同的是B1为standard,B2为singleTop。
若我意图打开的顺序为B1->B2->B2,则实际打开的顺序为B1->B2(后一次意图打开B2,实际只调用了前一个的onNewIntent方法)
若我意图打开的顺序为B1->B2->B1->B2,则实际打开的顺序与意图的一致,为B1->B2->B1->B2。


singleTask
只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。
如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。

例如:
若我的应用程序中有三个Activity,C1,C2,C3,三个Activity可互相启动,其中C2为singleTask模式,那么,无论我在这个程序中如何点击启动,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多个实例,但是C2只会存在一个,并且这三个Activity都在同一个task里面。
但是C1->C2->C3->C2->C3->C1-C2,这样的操作过程实际应该是如下这样的,因为singleTask会把task中在其之上的其它Activity destory掉。
操作:C1->C2          C1->C2->C3          C1->C2->C3->C2            C1->C2->C3->C2->C3->C1             C1->C2->C3->C2->C3->C1-C2
实际:C1->C2          C1->C2->C3          C1->C2                              C1->C2->C3->C1                               C1->C2

若是别的应用程序打开C2,则会新启一个task。
如别的应用Other中有一个activity,taskId为200,从它打开C2,则C2的taskIdI不会为200,例如C2的taskId为201,那么再从C2打开C1、C3,则C2、C3的taskId仍为201。
注意:如果此时你点击home,然后再打开Other,发现这时显示的肯定会是Other应用中的内容,而不会是我们应用中的C1 C2 C3中的其中一个。


singleInstance
只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。

例如:
程序有三个ActivityD1,D2,D3,三个Activity可互相启动,其中D2为singleInstance模式。那么程序从D1开始运行,假设D1的taskId为200,那么从D1启动D2时,D2会新启动一个task,即D2与D1不在一个task中运行。假设D2的taskId为201,再从D2启动D3时,D3的taskId为200,也就是说它被压到了D1启动的任务栈中。

若是在别的应用程序打开D2,假设Other的taskId为200,打开D2,D2会新建一个task运行,假设它的taskId为201,那么如果这时再从D2启动D1或者D3,则又会再创建一个task,因此,若操作步骤为other->D2->D1,这过程就涉及到了3个task了。

posted @ 2015-06-23 11:04 建华 阅读(145) | 评论 (0)编辑 收藏

2013年2月20日

蓝牙发送文件

系统4.0.3以后的
      File file=new File("");
 Uri uri1 = Uri.fromFile(file);
 Intent intent = new Intent();    
intent.setAction(Intent.ACTION_SEND);   
 //intent.setType("audio/*"); 
  intent.setType("application/octet-stream");
ComponentName comp=new ComponentName("com.mediatek.bluetooth","com.mediatek.bluetooth.BluetoothShareGatewayActivity");
intent.setComponent(comp);
 intent.putExtra(Intent.EXTRA_STREAM, uri1);
startActivity(intent);
系统4.0.3以前的
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
//这个类型函数是自己工具类的方法,你可以自己设置文件类型,例如图片文件:image/*  
  //不想写类型直接*/*也是可以的
intent.setType("audio/*");
//这里setClassName就是指定蓝牙,不写这句就弹出选择用什么发送
  //有蓝牙啊,gmail啊,彩信之类的
intent.setClassName("com.android.bluetooth" , "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File("")));
startActivity(intent);


  ArrayList<Uri> uris = new ArrayList<Uri>();
   uris.add(Uri.fromFile(new File("/sdcard/111.txt")));
   uris.add(Uri.fromFile(new File("/sdcard/222.txt")));
   
               Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.setType("video/*");
intent.setClassName("com.android.bluetooth" , "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
//intent.setClassName("com.mediatek.bluetooth","com.mediatek.bluetooth.BluetoothShareGatewayActivity");
//intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File("/sdcard/111.txt")) );
//intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File("/sdcard/222.txt")));
intent.putExtra(Intent.EXTRA_STREAM, uris);
startActivity(intent);

posted @ 2013-02-20 08:45 建华 阅读(548) | 评论 (0)编辑 收藏

2013年2月1日

Android中关于dip和px以及转换的总结

我们在页面布局的时候,经常会设置容器的长度,但是到底该使用哪个作为长度的单位而懊恼。在Android中支持的描述大小区域的类型有以下几种:

px(pixels)——像素:不同的设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多。

dip(device independent pixels)——设备独立像素:这个和设备硬件有关,一般我们为了支持WCGA、HVGA和QVGA推荐使用这个,不依赖于像素。等同于dp。

sp(scaled pixels—best for text size)——带比例的像素。

pt(points)——磅:1pt = 1/72英寸

in(inches)——英寸

mm(millimeters)——毫米

到底px和dip有什么区别呢?

dip != px

主要是针对不同设备而言的。在Density是160的设备上,比如用AVDManager创建的默认模拟器,dip和px是一样的但是如果同样的代码,换到不同Density的设备上,比如换到一个Density是240的设备上,dip和px体现出来的大小就不一样了。px不管在什么样的设备上都是那样长,但是dip会根据设备变化;WQVGA屏density=120;QVGA屏density=120;HVGA屏density=160;WVGA屏density=240;density值表示每英寸有多少个显示点,与分辨率是两个概念。

当屏幕density=240时使用hdpi标签的资源
当屏幕density=160时,使用mdpi标签的资源
当屏幕density=120时,使用ldpi标签的资源。

不加任何标签的资源是各种分辨率情况下共用的。布局时尽量使用单位dip,少使用px。

换算公式为:
pixs =dips * (densityDpi/160). 
dips=(pixs*160)/densityDpi

如何获得设备的屏幕分辨率和屏幕密度?
例如分辨率为480*800,密度为240的设备,方法如下


DisplayMetrics dm =getResources().getDisplayMetrics();
dm.densityDpi=240
dm.widthPixels=480
dm.heightPixels=800

posted @ 2013-02-01 10:08 建华 阅读(4793) | 评论 (2)编辑 收藏

2012年12月26日

在android模拟器中永久删除自带应用程序

首先启动android模拟器。
打开cmd命令行窗口。输入adb -s emulator-5554 shell
此时可以管理系统文件夹了,再输入ls
可以看到列出了文件夹和文件,输入cd system/app再输入ls
可以看到系统自带的应用程序apk文件,删除你想要删除的,例如Phone.apk,输入rm Phone.apk
此时会看到提示说rm failed for Phone.apk, Read-only file system那是因为这些是只读文件,我们没有权限删除它。所以接下来要做的是获取权限,首先查看权限,输入mount
可以看到/dev/block/mtdblock0 /system yaffs2 ro 0 0说明在system这个地方我们没有权限那么接下来我们就来获取权限,输入mount -o remount,rw -t yaffs2 /dev/block/mtdblock0 /system
没有提示错误,再次查看权限,输入mount
可以看到/dev/block/mtdblock0 /system yaffs2 rw 0 0
说明我们已经获取到权限了此时再输入rm Phone.apk就可以成功删除了

最后一点,就算你成功删除了,android模拟器每次启动时也会恢复回来。
那么如何永久删除呢,很简单,删除SdkSetup.apk,输入rm SdkSetup.apk
还没完,找到avd目录(一般在我的文档),进入xxxx.avd目录,删除cache.img和userdata-qemu.img
还有还有,找到%SDK_HOME%/platforms/android-X/images/system.img,复制到上面的目录中。
最后最后,再重启模拟器,大功告成!

posted @ 2012-12-26 18:17 建华 阅读(603) | 评论 (0)编辑 收藏

2012年3月23日

surfaceView 与View 的区别

如果你的游戏不吃CPU,用View就比较好,符合标准Android操作方式,由系统决定刷新surface的时机。

  但如果很不幸的,你做不到不让你的程序吃CPU,你就只好使用SurfaceView来强制刷新surface了,不然系统的UI进程很可能抢不过你那些吃CPU的线程。

  当然其实不止这两种方法来刷新Surface的,这两种只是纯Java应用比较常见的方法。

  SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。

  那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。

   当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中 thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。

  所以基于以上,根据游戏特点,一般分成两类。

  1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。

  2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。

posted @ 2012-03-23 16:33 建华 阅读(192) | 评论 (0)编辑 收藏

2012年2月9日

android多国语言文件夹

android多国语言文件夹文件汇总如下:

中文(中国):values-zh-rCN

中文(台湾):values-zh-rTW

中文(香港):values-zh-rHK

英语(美国):values-en-rUS

英语(英国):values-en-rGB

英文(澳大利亚):values-en-rAU

英文(加拿大):values-en-rCA

英文(爱尔兰):values-en-rIE

英文(印度):values-en-rIN

英文(新西兰):values-en-rNZ

英文(新加坡):values-en-rSG

英文(南非):values-en-rZA

阿拉伯文(埃及):values-ar-rEG

阿拉伯文(以色列):values-ar-rIL

保加利亚文:  values-bg-rBG

加泰罗尼亚文:values-ca-rES

捷克文:values-cs-rCZ

丹麦文:values-da-rDK

德文(奥地利):values-de-rAT

德文(瑞士):values-de-rCH

德文(德国):values-de-rDE

德文(列支敦士登):values-de-rLI

希腊文:values-el-rGR

西班牙文(西班牙):values-es-rES

西班牙文(美国):values-es-rUS

芬兰文(芬兰):values-fi-rFI

法文(比利时):values-fr-rBE

法文(加拿大):values-fr-rCA

法文(瑞士):values-fr-rCH

法文(法国):values-fr-rFR

希伯来文:values-iw-rIL

印地文:values-hi-rIN

克罗里亚文:values-hr-rHR

匈牙利文:values-hu-rHU

印度尼西亚文:values-in-rID

意大利文(瑞士):values-it-rCH

意大利文(意大利):values-it-rIT

日文:values-ja-rJP

韩文:values-ko-rKR

立陶宛文:valueslt-rLT

拉脱维亚文:values-lv-rLV

挪威博克马尔文:values-nb-rNO

荷兰文(比利时):values-nl-BE

荷兰文(荷兰):values-nl-rNL

波兰文:values-pl-rPL

葡萄牙文(巴西):values-pt-rBR

葡萄牙文(葡萄牙):values-pt-rPT

罗马尼亚文:values-ro-rRO

俄文:values-ru-rRU

斯洛伐克文:values-sk-rSK

斯洛文尼亚文:values-sl-rSI

塞尔维亚文:values-sr-rRS

瑞典文:values-sv-rSE

泰文:values-th-rTH

塔加洛语:values-tl-rPH

土耳其文:values--r-rTR

乌克兰文:values-uk-rUA

越南文:values-vi-rVN

posted @ 2012-02-09 15:21 建华 阅读(4457) | 评论 (0)编辑 收藏

2011年12月20日

如果task中已经有这个activity A,那么就把A拿到task的最顶层,而不是创建一个新的activity

Intent.FLAG_ACTIVITY_REORDER_TO_FRONT的意思是,如果task中已经有这个activity A,那么就把A拿到task的最顶层,而不是创建一个新的activity。

所以不加flag也不会影响界面的切过去,只是会影响task的顺序而已。

posted @ 2011-12-20 19:31 建华 阅读(218) | 评论 (0)编辑 收藏

2011年12月14日

Android开发小知识 ListView几个比较特别的属性

Android:stackFromBottom="true" 设置该属性之后你做好的列表就会显示在列表的最下面,值为true和false
android:transcriptMode="alwaysScroll" 要用ListView或者其它显示大量Items的控件实时跟踪或者查看信息,并且希望最新的条目可以自动滚动到可视范围内。通过设置的控件 transcriptMode属性可以将Android平台的控件(支持ScrollBar)自动滑动到最底部。 c
acheColorHint属性,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然后指定属性
android:background="@drawable/bg",不过当你这么做以后,发现背景是变了,但是当你拖动,或者点击list空白位置的 时候发现ListItem都变成黑色的了,破坏了整体效果。 如果只是换背景的颜色的话,可以直接指定
android:cacheColorHint为你所要的颜色,如果你是用图片做背景的话,那也只要将
android:cacheColorHint指定为透明(#00000000)就可以了
android:divider="@drawable/list_driver" 其中 @drawable/list_driver 是一个图片资源,如果不想显示分割线则只要设置为android:divider="@drawable/@null" 就可以了 android:scrollbars="none"与setVerticalScrollBarEnabled(true);的效果是一样的,不活动的 时候隐藏,活动的时候也隐藏 android:fadeScrollbars="true" 配置ListView布局的时候,设置这个属性为true就可以实现滚动条的自动隐藏和显示。 fadingEdge属性,上边和下边有黑色的阴影 android:fadingEdge="none" 设置后没有阴影了

posted @ 2011-12-14 20:14 建华 阅读(354) | 评论 (0)编辑 收藏

2011年12月13日

做一个透明的activity

<activity android:name=".usual.activity.Declaration" android:theme="@android:style/Theme.Translucent.NoTitleBar" />

posted @ 2011-12-13 14:13 建华 阅读(216) | 评论 (0)编辑 收藏

2011年11月24日

draw9patch不失真背景

1.背景自适应且不失真问题的存在
      制作自适应背景图片是UI开发的一个广泛问题,也是界面设计师渴望解决的问题,我相信我们彼此都深有体会。
      比如,列表的背景图一定,但是列表的高度随着列表数据项会发生变化;标题栏的背景,无论横屏还是竖屏,高分辨率还是低分辨率,都能自动填充满,而且不失真等等背景问题。
      根据以往的经验,我们一般采用先切图后拼凑的做法,这种做法本来我想在这里和大家介绍一下,其实有的时候还是很有用的,但是说起来会比较麻烦,就不说这个非重点了,略去,如果大家真的要介绍,在回复中说明,我再考虑一下。
     Android针对这种情况,专门制作了一种.9.PNG格式来解决这个问题。

2.9.PNG格式。
      我不想在这里过多的讨论PNG格式的定义问题。但是.9.PNG确实是标准的PNG格式,只是在最外面一圈额外增加1px的边框,这个1px的边框就是 用来定义图片中可扩展的和静态不变的区域。特别说明,left和top边框中交叉部分是可拉伸部分,未选中部分是静态区域部分。right和bottom 边框中交叉部分则是内容部分(变相的相当于定义看一个内边距,神似padding功能,后面我会单独介绍一下),这个参数是可选的, 如下图。
     在Android中以9.PNG格式的图片未背景,则能够自定义拉伸而不失真,比如系统的Button就是一个典型的例子。 
     其实呢,无论是left和top,还是right和bottom都是把图片分成9块 (边角四块是不能缩放的,其他的四块则是允许缩放的),所以叫做9.PNG。

3. 使用Draw9Patch.jar制作9.PNG图片之定义拉伸区域。
      前面已经了解到9.PNG格式的工作方式,下面我们使用谷歌提供的Draw9Patch(运行android-sdk-windows\tools目录下的Draw9Patch.bat)来制作.9.PNG图片。
      第一步:准备要拉伸的图片。
                                                           
      非常小的一张图片,我希望以此为背景,中间部分填充文章内容。
      第二步:制作.9.PNG图片
      打开Draw9Patch,把图片拖进去,如下:

      默认的拉伸是整体拉伸,其实边框部分我们并不想拉伸,好,我们自己来定义拉伸区域,如下图:

       然后点击File,导出为content.9.png。
       第三步:在layout文件中使用制作的 .9.PNG图片.
       新建工程Draw9Patch,默认主Activity为Draw9PatchActivity.java:

1@Override
2public void onCreate(Bundle savedInstanceState)
3{
4    super.onCreate(savedInstanceState);
5    setContentView(R.layout.main);
6}

      我们把content.9.png文件拷贝到/res/drawable文件夹下,打开/res/layout目录下的main.xml,申明如下:

01<?xml version="1.0" encoding="utf-8"?>
02<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="vertical"
04    android:layout_width="fill_parent"
05    android:layout_height="fill_parent"
06    android:background="#777"
07    android:padding="8dip"
08    >
09    <TextView
10    android:layout_width="fill_parent"
11    android:layout_height="wrap_content"
12    android:text="正文:A NinePatchDrawable graphic is a stretchable bitmap image."
13    android:background="@drawable/content"
14    android:textColor="#000"
15    />
16</LinearLayout>

     如图,

     我们修改text,

01<?xml version="1.0" encoding="utf-8"?>
02<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="vertical"
04    android:layout_width="fill_parent"
05    android:layout_height="fill_parent"
06    android:background="#777"
07    android:padding="8dip"
08    >
09<TextView
10    android:layout_width="fill_parent"
11    android:layout_height="wrap_content"
12    android:text=" 正文:A NinePatchDrawable graphic is a stretchable bitmap image, which Android will automatically resize to accommodate the contents of the View in which you have placed it as the background. A NinePatch drawable is a standard PNG image that includes an extra 1-pixel-wide border."
13    android:background="@drawable/content"
14    android:textColor="#000"
15    />
16</LinearLayout>

      如图,

      可以看出,边框非常的清晰。下图是未使用.9.PNG的对比图,而且也不是我们要的效果:

      到这里为止,我们已经基本会制作.9.PNG图片了。为了知识体系的全面性和深入性,我们继续。

4.使用Draw9Patch.jar制作9.PNG图片之定义内容区域。
      是不是觉得文字和边距挨的太近,好,我们使用right和bottom边的线来定义内容区域,来达到增大内边距的目的。

      我们定义了一个很小的内容区域,其他的地方则自动充当边框,从而使内边距显的很大,如下图,

      在这里,我要特别说明,一开始为了增大内边距,很容易惯性思维,在<TextView>中申明 android:padding="10dip" 之类的,我在这里劝告朋友们不要这么做,一是你将无法预知你的显示,二是这比较混淆,因为设置内容区域就是确定padding,所以我在前面部分说他们是 神似。我个人认为通过内容区域设定padding比在布局xml中定义padding更优雅,更简洁!
      关于Draw9Patch工具的其他使用说明,我在次不再累述,因为要说的话太多,为了节省篇幅,请参考官方文档。

5.制作.9.PNG的高级技巧。
       对于初学Draw9Patch的人来说,这可以算是高级技巧,那就是:拉伸区域,可以不是连续的,可以不止一块,而且是和自定义的边框线的长度成正比。
       直接上图说明:
 

6.SDK中如何处理9.PNG图片。
      SDK专门针对9.PNG做了定义和处理,这里我们只是做个简单的流程分析,Bitmap在读取图像流数据的时候,会把判断图片的 NinePatchChunk(9Patch数据块),如果NinePatchChunk不为空,则是 NinePatchDrawable,NinePatchDrawable则又会交给NinePatch处理:

1setNinePatchState(new NinePatchState(
2               new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"),
3               padding, dither), r);

      NinePatch检验成功则调用本地方法,绘制出最终的图片:

1nativeDraw(canvas.mNativeCanvas, location,
2                mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0,
3                canvas.mDensity, mBitmap.mDensity);

7.android系统中大量应用了9.PNG图片。
     通过解压随便一个rom,找到里面的framework_res.apk,里面有大量的9.PNG格式文件,被广泛的应用起来,比如常见的有:
     按钮:  
     解锁:  
     下拉框:  
     标题栏:
     Toast:
      还有搜索,键盘,放大缩小控件,时间加减等等,我就不一一列举。

8.最后送上一些图例,以飨读者,以做后鉴:
 
赏图1 本人之作

 赏图2 下拉按钮
 
赏图3 文章头部背景 
 
赏图4 系统头部背景
转载于
http://www.cnblogs.com/qianxudetianxia/archive/2011/04/17/2017591.html

posted @ 2011-11-24 15:00 建华 阅读(1129) | 评论 (1)编辑 收藏