android 面试必备(整理)


38. 请描述下Activity的生命周期。 必调用的三个方法:onCreate() --> onStart() --> onResume(),用AAA表示
  (1)父Activity启动子Activity,子Actvity退出,父Activity调用顺序如下
  AAA --> onFreeze() --> onPause() --> onStop() --> onRestart()--> onStart(),onResume() …
  (2)用户点击Home,Actvity调用顺序如下
  AAA --> onFreeze() --> onPause() --> onStop() -- Maybe -->onDestroy() – Maybe
  (3)调用finish(), Activity调用顺序如下
  AAA --> onPause() --> onStop() --> onDestroy()
  (4)在Activity上显示dialog,Activity调用顺序如下
  AAA
  (5)在父Activity上显示透明的或非全屏的activity,Activity调用顺序如下
  AAA --> onFreeze() --> onPause()
  (6)设备进入睡眠状态,Activity调用顺序如下
  AAA --> onFreeze() --> onPause()
39.对于多Activity的应用来说,在打开多个Activity后,如果想在最后打开的Activity直接退出,上边的方法都是没有用的,因为上边的方法都是结束一个Activity而已。
1、抛异常强制退出:
2、记录打开的Activity:
  每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。
3、发送特定广播:
  在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。
4、递归退出
 在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。




-----------------------------------------------------------------------------------------
动画(animation):alpha 淡入淡出,scale缩放,Rotate旋转,Translate移动
例子:AlphaAnimation aa = new AlphaAnimation(1, 0);
    // 设置动画持续时间为2秒
    aa.setDuration(2000);
    // 开始动画,使用将要发生动画的控件对象调用startAnimation
    view.startAnimation(aa);


1.onCreate(),onStart(),onrestart,onresume,onpause,onstop,ondestory
2.Framelayout,Linearlayout,relativelayout,tablelayout,AbsoluteLayout
Android:layout_toLeftOf="", Android:layout_below="".
android:layout_toRightOf="", android:layout_above=""
include,   android:layout_weight="1"
3.startservice,bindservice.
4.sharedpreference,文件,SQlite,contentprovider


5.请继承SQLiteOpenHelper实现:
public class DBhelper extends SQliteOpenhelper{
public final static String  databasename="diaryOpenHelper.db";
public final static int databaseversion=1;
  private static final String CREATE_TABLE_SETTINGS = "create table " + settings_table+ " (_id integer primary key autoincrement , set_option TEXT , set_values integer);";
public DBHelper(Context context){
super(context,databasename,null,databasename);


       }
       public void onCreate(SQliteDatabase db){
         String sql="create table diary"+"("+"_id integer primary key autoincrement,"+
"topic varchar(100),"+"content varchar(100)"+")";


db.execSQl(sql);
}
      public void onUpgrade(SQLiteDataBase db,int oldVersion,int newVersion){
String sql="drop table if extists diary"
db.execSQL(sql);
this.OnCreate(db);
}
}

6.简要解释一下activity、intent 、intent filter、service、BroadcaseReceiver、ContentProvider
一个activity 呈现了一个用户可以操作的可视化用户界面。Activity 是Context 的子类同时
实现了window.callback 和keyevent.callback 可以处理与窗体用户交互的事件。
一个service 不包含可见的用户界面,而是在后台无限地运行可以连接到一个正在运行的服
务中,连接后,可以通过服务中暴露出来的接口与其进行通信。简单说就是方便应用程序内
的进程间通讯。
一个broadcast receiver 是一个接收广播消息并作出回应的component,broadcast receiver 没有
界面
ContentProvider 内容提供者。
一个intent 是一个Intent 对象,它保存了消息的内容。对于activity 和service 来说,它指定
了请求的操作名称和待操作数据的URI
Intent 对象可以显式的指定一个目标component。如果这样的话,android 会找到这个
componen(t 基于manifest 文件中的声明)并激活它。但如果一个目标不是显式指定的,android
必须找到响应intent 的最佳component。
它是通过将Intent 对象和目标的intent filter 相比较来完成这一工作的。一个component 的
intent filter 告诉android 该component 能处理的intent。intent filter 也是在manifest 文件中声
明的。


7.如果后台的Activity 由于某原因被系统回收了,如何在被系统回收之前保存当前
状态?
onSaveInstanceState()
当你的程序中某一个Activity A 在运行时,主动或被动地运行另一个新的Activity B,这个时候A 会执
行onSaveInstanceState()。B 完成以后又会来找A,这个时候就有两种情况:一是A 被回收,二是A 没有
被回收,被回收的A 就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数
savedInstanceState;而没被收回的就直接执行onResume(),跳过onCreate()了。


8.如何退出Activity?如何安全退出已调用多个Activity的Application?
在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理.递归关闭,使用finish().


9.onSaveInstanceState()  killProcess() System.exit()


10.将一个Activity设置成窗口的样式.
在AndroidManifest.xml 中定义Activity 的地方一句话android:theme="@android:style/Theme.Dial
og"或android:theme="@android:style/Theme.Translucent"就变成半透明的


11.关于Android Dvm的进程和linux的进程,应用程序的进程说法正确的是:
Dvm指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例.而每一个Dvm都是在Linux中的一个进程.所有说可以认为是同一个概念.


12.横竖屏切换时的生命周期
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
onSaveInstanceState--> onPause-->onStop-->onDestroy--> onCreate--> onStart-->onRestoreInstanceState->onResume-->
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法


13.http,TCP,UDP 怎样判断数据包的完整性,它们各自的特点和区别.
 http协议即超文本协议,是建立在tcp协议之上的一种应用.特点:客户端发送的每次请求都需要服务器回送响应,在请求结束后会主动释放连接,http连接是一种"短连接".
tcp:面向连接,提供差错检测和重传服务. (正在通信前必须要与对方建立连接)
UDP:是无连接的,基本上只是对数据做简单的封装后直接交给Ip层发送. (正式通信不必与对方建立连接,不管对方状态就直接发送)


Socket是一套建立在Tcp/IP协议上的接口.  
Socket连接与Http连接区别:socket连接一旦确认,相互发送内容,直到对方连接断开,但实际网络应用中,客服端连接受路由器,网关,防火墙等.
而http连接使用的是"请求--响应"的方式,不仅在请求时需要先建立连接,而且需要客户端向服务端发送请求后,服务端才能回发数据.
Scoket连接与TCP连接:创建Socket连接时,可以指定使用的传输层协议(TCP,UDP),当使用TCP协议进行连接时,该Socket连接就是一个Tcp连接.


14.android中的动画有哪几类,它们的特点和区别是什么?
Tween和Frame动画.Tween动画这种实现方式 可以使视图组件移动,放大,缩小以及产生透明度的变化。Frame动画,传统的动画方式,通过顺序的播放排列好的图片来实现,类似电影。


15.说说MVC模式的原理,它在Adnroid中的运用
MVC:模型—视图-控制器  由这三个部分组成。模型对象:是应用程序的主题部分,所有的业务逻辑都应该写在改层。视图层:是应用程序中负责生成用户界面的部分。控制器:控制用户界面数据显示及更新model对象状态的部分。
android中的运用:
视图层(View) 采用xml文件来进行界面的描述。
控制器(controller): activity ,activity中不要写代码,要通过Activity交割model业务逻辑层处理。
模型层(model):对数据库的操作,对网络等操作都应该放在model里面处理.包括业务计算


16.DDMS和TraceView的区别
DDMS是一个程序执行查看器,在这里可以看见线程和堆在等信息。TreaceView是程序性能分析器。


17.activity和Task的启动模式有哪些,每种含义是什么?
standard,singleTop,singleTask,singleInstance
standard 每次都会新建,每个Task都可以有,且每个Task都可以有多个实例;
singleTop 当前实例如果在栈顶,就不新建实例,调用其OnNewIntent。 如不在栈顶,则新建实例;
singleTask 新建一个Task,如果已经有其他的Task并且包含该实例,那就直接调用那个Task的实例。
singleInstance 新建一个Task,且在该Task中只有它的唯一一个实例


18.android view,surfaceview,glsurfaceview的区别
SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView
SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。 
所以基于以上,根据游戏特点,一般分成两类。 
1)被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。 
2)主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。 


19.android的系统架构
android系统架构分从下往上为
linux内核层(linuxkernel)
本地库:媒体库、SQLite,WebKit等
Android运行时:包括核心库(android.os、android.net、android.media)和Dalvik虚拟机
应用程序框架层applicationframework:通知管理器,内容提供者,窗口管理器等 
应用程序层(applications):例如电子邮件、短信、日历、地图、浏览器和联系人管理等


20.系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原由:
答:通过直接发送Uri把参数带过去,或者通过manifest里的intentfilter里的data属性。代码如下:
 Intent intent = new Intent();
Intent.setAction(“android.intent.action.View”);
Uri uriBrowsers = Uri.parse(“http://www.sina.com.cn”);
Intent.setData(uriBrowsers);
//包名、要打开的activity
intent.setClassName(“com.android.browser”,”com.android.browser.BrowserActivity”);
startActivity(intent);


21.如何将打开res raw目录中的数据库文件?
答:在Android中不能直接打开res raw目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或SD卡的某个目录中,然后再打开该数据库文件。复制的基本方法是使用getResources().openRawResource方法获得res aw目录中资源的 InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法来打开任意目录中的SQLite数据库文件。


22.android 中有哪几种解析xml的类?官方推荐哪种?以及它们的原理和区别:
答:XML解析主要有三种方式,SAX、DOM、PULL。常规在PC上开发我们使用Dom相对轻松些,但一些性能敏感的数据库或手机上还是主要采用SAX方式,
SAX读取是单向的,优点:不占内存空间、解析属性方便,但缺点就是对于套嵌多个分支来说处理不是很方便。
DOM方式会把整个XML文件加载到内存 中去,
PULL常常用在J2ME对于节点处 理比较好,类似SAX方式,同样很节省内存。
Sax解析步骤:
创建解析工厂 SaxparseFactory factory=SaxParseFactory.newInstance();
//创建Sax解析器 SaxParser parse=factory.newSaxParse();
//创建自定义defaultHandler对象 MyDefaultHandler handler=new MydefaultHandler();
parse.parse(isStream,handler);


Pull解析步骤 //得到pull解析器 XmlPullParse parse=XmlPullparseFactory.newInstance.newPullparse();
parse.setInut(new StringReader(xmlMsg));
int eventType=parse.getEventType();//节点事件
While(!eventType==XmlPullParse.End_Document){
    String elementName=parse.getName();//节点名称
    if(eventType==XmlPullParse.START_TAG){
IF("节点名称".equals(elementName)){
           String value=parse.getValue();//值
}
    }
   eventType=parse.next();
}
Sax 与pull 的区别: 1.sax 是通过回调方法将tag/value 值直接传来,而pull 则只告诉一个节点开
始或结束,要取里面的值需到parser 里面取。3.pull 代码更加简介。谷歌官方推荐pull。


23.谈谈Android的IPC机制:
答:IPC是内部进程通信的简称,是共享"命名管道"的资源。Android中的IPC机制是为了让Activity和Service之间可以随时的进行交互,故在Android中该机制,只适用于Activity和Service之间的通信,类似于远程方法调用,类似于C/S模式的访问。通过定义AIDL接口文件来定义IPC接口。Servier端实现IPC接口,Client端调用IPC接口本地代理。
 
24.android的service的生命周期?哪个方法可以多次被调用:
答:1)与采用Context.startService()方法启动服务有关的生命周期方法
onCreate() -> onStart() -> onDestroy()
onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。
onDestroy()该方法在服务被终止时调用。
2)与采用Context.bindService()方法启动服务有关的生命周期方法
onCreate() -> onBind() -> onUnbind() -> onDestroy()
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。多次调用Context.bindService()方法并不会导致该方法被多次调用。
onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。onCreate() ->onStart() ->onBind() ->onUnbind()[重载后的方法需返回true] ->onRebind()


25.handler进制的原理:
答:android提供了handler和looper来满足线程间的通信。Handler先进先出原则。looper用来管理特定线程内对象之间的消息交换(message Exchange).
    1)looper:一个线程可以产生一个looper对象,由它来管理此线程里的message queue(消息队列)
   2)handler:你可以构造一个handler对象来与looper沟通,以便push新消息到messagequeue里;或者接收looper(从messagequeue里取出)所送来的消息。
   3)messagequeue:用来存放线程放入的消息。
   4)线程:UI thread 通常就是main thread,而android启动程序时会为它建立一个message queue.


26.注册广播有几种方式, 这些方式有何忧缺点?Adnroid引入广播机制的用意?
两种,一种Android.manifest中配置广播
<receiver android:name=".MyBroadCaseReceiver">
<intent-filter>
<action android:name="action名称">
</intent-filter>
</receiver>
动态注册:
//实例化广播 MyBoradCastReceiver receiver=new MyBoradCastReceiver();
//实例化过滤器,并指定相同action的广播
IntentFilter filter=new IntentFilter();
filter.addAction(DwonloadsConstants.Impl.UPDATACTION);
//注册广播 MyBoradCastActivity.this.registerReceiver(receiver,filter);
二者区别: 代码注册属于非常驻型广播,会随这应用程序的结束而结束,而xml中配置型广播属于常驻型广播比如程序检测网络,程序已经退出如果有网络,则会接受到广播而自动启动程序.Xml;配置型广播因为是常驻型广播所有耗电.
注销广播的方法:unregisterReceiver(myBroadCastReceiver);
发送广播:sendBoradCast(intent);
广播的生命周期:广播接收器仅在执行onReceiver方法时处于活动状态,当onRecevier返回后,即结束.
用意:
1.方便几大组件的信息和数据交互
2.应用之间互通消息(如:自己的应用程序监听系统来电)
3:效率上(参考UDP的广播协议在局域网的方便性)
4:设计模式上(反转控制的一种应用,类似监听者模式)


27. 如何启用Service,如何停用Service
Context.startService() 或Context.bindService()
Context.stopService(),Context.stopSelf();


28.打开assets 文件夹中的文件
getResources().getAssets().open("name.txt");


29.Android 的数据存储方式。
SharedPreferences 方式,文件存储方式,SQLite 数据库方式,内容提供器(Content provider),
网络存储方对应的目录/data/data/Package Name/Shared_


30.获取网络内容的方式。
HttpClient , HttpUrlConnection
HttpClient:
//实例化Httpclient HttpClient client = new DefaultHttpClient();
//实例化post 请求对象HttpPost request = new HttpPost(url);
// 执行post 请求HttpResponse response = client.execute(request);
//如果响应码等于200 则请求成功获取信息。
If( response.getStatusLine().getStatusCode() == 200){
//获取内容
InputStream inStream = response.getEntity().getContent();
//TODO 处理流
}
HttpUrlConnection
// 实例化URL URL url = new URL(url);
//取得连接对象HttpUrlConnection conn = (HttpUrlConnection)url.openConnection();
//设置连接属性conn.setConnectTimeOut(6*1000);
//设置请求方式conn.setRequestMethod("POST");
Conn.connect();
//获取返回码int responseCode = conn.getResponseCode();
If(responseCode == 200){
//回去返回内容
InputStream inStream = conn.getInputStream();
//TODO 处理流
}


31.Android 数字签名
个人理解: 作用:区分应用程序来自哪个开发人员或哪家公司。
数字签名包含以下几点: 1.所有的应用程序都必须有数字证书,Android
系统不会安装一个没有数字证书的应用程序2.如果要正式发布一个Android 程序,必须使
用一个合适的私钥生成的数字证书来给程序签名。3.数字签名具有有效期。


32.View 的刷新:
在需要刷新的地方,使用handle.sendmessage 发送信息,然后在handle 的
handleMessage 里面执行invalidate 或者postinvalidate.


33.GC 内存泄露
出现情况:
1.数据库的cursor 没有关闭
2.构造adapter 时,没有使用缓存convertView
衍生listview 的优化问题-----减少创建view 的对象,充分使用convertView,可以使用一
静态类来优化处理getview 的过程/
3.Bitmap 对象不使用时采用recycle()释放内存
4.activity 中的对象的生命周期大于activity
调试方法: DDMS==> HEAPSZIE==>dataobject==>[Total Size]




5.不用的对象可以把它指向null
6.适量使用缓存,不要过量使用,因为内存有限,能保存路径地址的就不要存放
图片资源,不经常使用的尽量不要缓存,不用是就清空.
---------------------------------------------------
android 性能优化:
控制程序耗电量:
解决方案:
1.大数据量下载时,采用GZIP解压缩,
2.使用效率高的数据格式和解析方式.
3.在需要网络连接的程序中,首先检测网络连接是否正常,
如果没有网络连接,那么就不需要执行相应的程序.
---
提高性能的几点技巧
1.减少临时对象的频繁生成和销毁
2.循环或者多层循环内的操作尽量可能简单
3.占用cpu较多的数据操作尽可能放在一个单独的线程中进行。
---
在使用内存消耗型任务时,使用压缩,缓冲和流等方式
在处理cpu消耗型任务时采用额外线程处理,UI线程展示的方式


37.ListView 如何优化
1.复用convertView,2.异步加载数据,分页加载。3.使用ViewHolder(使用静态的view 避
免创建过多的view,把布局里面的组件都封装起来,避免重复实例化)
当convertView为空时,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象。当convertView不为空,重复利用已经创建的view的时候,使用getTag()方法获取绑定的ViewHolder对象,这样就避免了findViewById对控件的层层查询,而是快速定位到控件


31.Android UI 中的View 如何刷新
在主线程中拿到view调用Invalide()方法, iv.invalidate();
在子线程里面可以通过postInvalide()方法;
new Thread(){
public void run(){
iv.postInvalidate();
}
}.start();


34.json 数据结构:对象和数组,jsonObject,jsonArray
jsonObject {key : value,key : value}
jsonArray [{key ; value,key:value},{key:value,key:value}]


35.两个activity 之间怎么传递数据?
Bundle bundle = new Bundle();
bundle.putShort(key, value);
intent.putExtras(bundle);
获取到激活他的getIntent();
Intent intent = getIntent();
Bundle bundle = intent.getExtras();


Bundle 类似map的集合
intent.getStringExtra("key","value");
intent.getBooleanExtra("key","value")


36.什么是IntentService?有何优点?
普通的service ,默认运行在ui main 主线程
Sdk 给我们提供的方便的,带有异步处理的service 类,
异步处理的方法OnHandleIntent()
OnHandleIntent() 处理耗时的操作




38.activity 生命周期。
onCreate 在这里创建界面,做一些数据的初始化工作onStart 界面可见
不可交互onResume: 变成和用户可交互的onPause: 到这一步是可见但不可交互的已经失去焦点。
onstop: 变得不可见,被下一个activity 覆盖了onDestroy 销毁。
onPause,onstop, onDestroy,三种状态下activity 都有可能被系统干掉onRestart


40.Contentprovider(内容提供商)
支持在多个应用中存储和读取数据,这也是跨应用共享数据的唯一方式。Android 中已有大
量内置contentprovider,如:联系人,相册,音频,视频。
Uri 类简介
Uri 代表了要操作的数据,Uri 主要包含了两部分信息:1.需要操作的ContentProvider ,
2.对ContentProvider 中的什么数据进行操作,一个Uri 由以下几部分组成:
1.scheme:ContentProvider(内容提供者)的scheme 已经由Android 所规定为:content://。
2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标
识来找到它。
如果要把一个字符串转换成Uri,可以使用Uri 类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")
UriMatcher 和ContentResolver 简介
UriMatcher:用于匹配Uri
ContentResolver:当外部应用需要对ContentProvider 中的数据进行添加、删除、修改和查询
操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用
Activity 提供的getContentResolver()方法。ContentResolver 使用insert、delete、update、
query 方法,来操作数据


41.关于音视频
图片缓存之二LruCache
    int memClass = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();  
            int cacheSize = 1024 * 1024 * memClass / 4;  //系统可用内存的1/4  
            mLruCache = new LruCache<String, Bitmap>(cacheSize) {  
                @Override  
                protected int sizeOf(String key, Bitmap value) {  
                    if (value != null)  
                        return value.getRowBytes() * value.getHeight();  
                    else  
                        return 0;  
                }  
                                                                         
                @Override  
                protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {  
                    if (oldValue != null)  
                        // 缓存容量满的时候,会根据LRU算法把最近没有被使用的图片转入此软引用缓存  
                        mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));  
                }  
            };  


3.实例化一个播放器mediaplayer= new MediaPlayer();
        mediaplayer.setDataSource("http://www.bogotobogo.com/Video/sample.3gp");//设置数据源
        mediaplayer.setDisplay(surfaceholder);//设置显示到刚才的surfaceview
        mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置流格式
        mediaplayer.prepare();
        mediaplayer.start();


100.Android 中 更新视图的函数ondraw() 和dispatchdraw()的区别  


绘制VIew本身的内容,通过调用View.onDraw(canvas)函数实现
绘制自己的孩子通过dispatchDraw(canvas)实现


View组件的绘制会调用draw(Canvas canvas)方法,draw过程中主要是先画Drawable背景,对 drawable调用setBounds(),然后是draw(Canvas c)方法。有点注意的是背景drawable的实际大小会影响view组件的大小,drawable的实际大小通过getIntrinsicWidth()和getIntrinsicHeight()获取,当背景比较大时view组件大小等于背景drawable的大小。
     
画完背景后,draw过程会调用onDraw(Canvas canvas)方法,然后就是dispatchDraw(Canvas canvas)方法,dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和 getIntrinsicWidth(),getIntrinsicHeight()方法,然后设为背景。




39.intent 意图,请描述一下Intent 和Intent Filter
例:打电话意图Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + number));
startActivity(intent);
intent-filter 说明activity 可以接收哪些action
Android 中通过Intent 对象来表示一条消息,一个Intent 对象不仅包含有这个消息的目
的地,还可以包含消息的内容,这好比一封Email,其中不仅应该包含收件地址,还可以包
含具体的内容。对于一个Intent 对象,消息“目的地”是必须的,而内容则是可选项。
通过Intent 可以实现各种系统组件的调用与激活.
Intent filter: 可以理解为邮局或者是一个信笺的分拣系统…
这个分拣系统通过3 个参数来识别
Action: 动作Intent.ation_view
Data: 数据uri uri mime
Category : 而外的附加信息
Action 匹配
Action 是一个用户定义的字符串,用于描述一个Android 应用程序组件,一个Intent
Filter 可以包含多个Action。在AndroidManifest.xml 的Activity 定义时可以在其
<intent-filter >节点指定一个Action 列表用于标示Activity 所能接受的“动作”,例
如:
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<action android:name="cn.itcast.action" />
……
</intent-filter>
如果我们在启动一个Activity 时使用这样的Intent 对象:
Intent intent =new Intent();
intent.setAction("cn.itcast.action");
那么所有的Action 列表中包含了“cn.itcast”的Activity 都将会匹配成功。
Android 预定义了一系列的Action 分别表示特定的系统动作。这些Action 通过常量的方
式定义在android.content. Intent 中,以“ACTION_”开头。我们可以在Android 提供
的文档中找到它们的详细说明。
URI 数据匹配
一个Intent 可以通过URI 携带外部数据给目标组件。在<intent-filter >节点中,通过
<data/>节点匹配外部数据。
mimeType 属性指定携带外部数据的数据类型,scheme 指定协议,host、port、path 指定
数据的位置、端口、和路径。如下:
<data android:mimeType="mimeType" android:scheme="scheme"
android:host="host" android:port="port" android:path="path"/>
电话的uri tel: 12345 package:cn.itcast.xxx
http://www.baidu.com
自己定义的uri itcast://cn.itcast/person/10
如果在Intent Filter 中指定了这些属性,那么只有所有的属性都匹配成功时URI 数据匹
配才会成功。
Category 类别匹配
<intent-filter >节点中可以为组件定义一个Category 类别列表,当Intent 中包含这个
列表的所有项目时Category 类别匹配才会成功。
默认是DEFAULT








 Activity有一个重要的属性process,这个属性是指定Activity运行时所在的进程。没有指定此属性的话,所有程序组件运行在应用程序默认的进程中,这个进程名跟应用程序的包名一致。中所有组建元素的process属性能够为该组件设定一个新的默认值。但是任何组件都可以覆盖这个默认值,允许你将你的程序放在多进程中运行。如果这个属性被分配的名字以:开头, 当这个activity运行时, 一个新的专属于这个程序的进程将会被创建。


以下面的代码为例,项目中有两个Activity,其中一个采用默认属性,另一个为其指定process属性以及新的ICON,这样该项目安装到设备上之后可以发现多了两个应用程序图标,一个是应用程序默认的图标,点击后进入HelloWorldActivity;另一个是手动指定的ICON,点击后进入NextPageActivity。这时使用adb shell查看进程可以发现,两个Activity是运行在不同的进程中的。


AndroidManifest.xml的主要内容如下:


<activity android:name=".HelloWorldActivity"
          android:label="@string/app_name"
          android:process=":process.main">
         <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
</activity>
 
<activity android:name="cn.ian.NextPageActivity"
 android:label="@string/nextpage"
 android:process=":process.sub"
 android:icon="@drawable/icon1"
 android:launchMode ="singleInstance">
<intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
</activity>




通过上面的方式,为App的各个组件指定process和icon属性,便能够达到类似于一个apk中打包多个程序(模块)的目的。


ps:要特别注意,为Activity指定process属性后,还必须为其指定launchMode为singleInstance,这样才有效。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值