Android的基本问题及答案

来源:互联网 发布:页面加载完成后执行js 编辑:程序博客网 时间:2024/05/22 05:31
Android应用程序四大组件分别是什么?Android有四大组件:Activity、Service、Broadcast Receiver、Content Provider

各个组件所起到的作用是什么?

1、activity 显示界面(显示的界面都是继承activity完成的)service 服务(后台运行的,可以理解为没有界面的activity)Broadcast Receiver 广播(做广播,通知时候用到)Content Provider  数据通信(数据之间通信,同个程序间数据,或者是不同程序间通信)

Android应用的目录组织结构,每个文件夹及文件的用途

src: 该文件夹是放项目的源代码的,存放Java代码

gen: 该文件夹下面有个R.java文件,R.java是在建立项目时自动生成的,这个文件是只读模式的,不能更改。R.java文件中定义了一个类——R,R类中包含很多静态类,且静态类的名字都与res中的一个名字对应,即R类定义该项目所有资源的索引。

project.properties: 指定当前工程采用的开发工具包的版本

libs: 当前工程所依赖的jar包.

assets: 放置一些程序所需要的媒体文件.

bin: 工程的编译目录. 存放一些编译时产生的临时文件和当前工程的.apk文件.

res(resources):资源目录,包含项目中的资源文件并将编译进应用程序。向此目录添加资源时,会被R.java自动记录。新建一个项目,res目录下会有三个子目录:drawabel、layout、values。

drawable: 存放程序所用的图片.

layout: 存放Android的布局文件.

values (应用程序所需要的数据. 会在R文件中生成id)

menu: 存放android的OptionsMenu菜单的布局.

strings.xml 存放android字符串.

AndroidManifest.xml: 项目的总配置文件,记录应用中所使用的各种组件。这个文件列出了应用程序所提供的功能,在这个文件中,可以指定应用程序使用到的服务(如电话服务、互联网 服务、短信服务、GPS服务等等)。另外当新添加一个Activity的时候,也需要在这个文件中进行相应配置,只有配置好后,才能调用此Activity。

Android中如何进行事件处理?事件源是什么?事件处理类是什么?

注册事件监听又是怎么回事?

Android提供了强大的事件处理机制,它包括两套处理机制:

1.基于监听的事件处理

2.基于回调的事件处理

对于Android基于监听的事件处理,主要的做法是为Android界面组件绑定特定的事件监听器。

对于Android基于回调的事件处理,主要的方法是重写Android组件特定的回调方法或者重写

Activity的回调方法

一、基于监听的事件处理

    在事件监听的处理模型中,主要涉及如下三类对象:

1.Event Source(事件源):事件发生的场所,通常就是各个组件、例如按钮、窗口、菜单等。

2.Event(事件):事件封装了界面组件上发生的特定事情(通常就是一次用户操作)。

3.Event Listener(事件监听器):扶着监听事件源所发生的事件,并对各种事件做出相应的响应。

    内部类可以作为事件监听器类,如果某个监听器要被多个GUI界面所共享我们可以使用外部类

作为事件监听器类,还有一种是匿名内部类作为事件监听器类,这里就不详细介绍了。

    Android还中还有一种更简单的绑定事件监听器的方式,直接在界面布局中为指定的标签绑定事件处理方法。

如:android:onClick="clickHandler",这样就意味着开发者需要在该界面布局对应的Activity中定义一个void clickHandler(View source),该方法将会处理该按钮上的单击事件。

基于监听的事件处理分工明确,可维护性高,且会优先触发。
内部类形式:Class MyClickListener implements View.OnClickListener{ 实现的方法,即事件处理器}
外部类形式:将事件监听器类定义成一个外部类:public class SendSmsListener implements OnLongClickListener{容易把业务逻辑和显示逻辑耦合,不利于程序的内聚性:p195}
Activity本身作为事件监听器:让Activity本身实现监听器接口,并实现处理方法。做法简洁,Activity本身应该完成界面的初始化工作,同时包含事件处理比较混乱。public
匿名内部类形式:btn.setOnClickListener( new OnClickListener(){ 实现时间的处理方法 });
绑定到标签:在XML未指定标签绑定事件处理方法,android:onClick= "clickHandler",写一个clickHandler(){处理 }方法。

Activity创建流程是怎样的

创建一个android activity
1、首先创造一个项目
2、填好项目的相关属性
3、创建一个Activity类的子类类.Eclipse使用alt+/快捷键可以自动完成父类
4、在rec/layout文件夹里创建布局xml页面 new->others->android->android xml file
5、注册刚才创建的activity子类到AndroidManifest.xml,运用eclisps可以可视化添加,双击AndroidManifest.xml 选择标签application->add->activity ,输入刚才创建的类名
到此,一个可以使用的activity即创建完成了,下一步是添加UI元素及实现页面响应代码
下面以添加一个checkbox为例说明,实现的效果是点击主Activity界面,跳转到CheckboxActivity界面
1、向主Activity界面添加一个button.打开main..xml,使用outline窗口的“+”,添加一个button,填写button的属性
2、在src/ActivityMain类,即主Activity的界面响应类中实现页面跳转代码,
2.1 声明 button 变量和监听器OnClickListener
2.2 实现OnClickListener监听器的跳转逻辑,即onClihck函数
2-3 绑定监听器OnClickListener到 button 中
3、向checkboxActivity界面添加一个 checkbox 的 widget
4、向checkboxActivity界面添加呈现代码

Activity的生命周期是怎样的

我们来看一下这一张经典的生命周期流程图:

相信不少朋友也已经看过这个流程图了,也基本了解了Activity生命周期的几个过程,我们就来说一说这几个过程。

1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。

2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。

3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。

4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。

5.用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。

6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。

7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。

除了几个常见的方法外,还有onWindowFocusChanged、onSaveInstanceState、onRestoreInstanceState方法:

1. onWindowFocusChanged方法:在Activity窗口获得或失去焦点时被调用,例如创建时首次呈现在用户面前;当前 Activity被其他Activity覆盖;当前Activity转到其他Activity或按Home键回到主屏,自身退居后台;用户退出当前 Activity。以上几种情况都会调用onWindowFocusChanged,并且当Activity被创建时是在onResume之后被调用,当 Activity被覆盖或者退居后台或者当前Activity退出时,它是在onPause之后被调用。

2. 这个方法在某种场合下还是很有用的,例如程序启动时想要获取视特定视图组件的尺寸大小,在onCreate中可能无法取到,因为窗口Window对象还没创建完成,这个时候我们就需要在onWindowFocusChanged里获取;如果大家已经看过我写的Android动画之Frame Animation这 篇文章就会知道,当时试图在onCreate里加载frame动画失败的原因就是因为窗口Window对象没有初始化完成,所以最后我将加载动画的代码放 到了onWindowFocusChanged中,问题迎刃而解。不过大家也许会有疑惑,为什么我在代码里将它注释掉了,因为对当前Activity每一 个操作都有它的执行log,我担心这会影响到整个流程的清晰度,所以将它注掉,大家只要了解它应用的场合和执行的顺序就可以了。

3. 2.onSaveInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,此方法会被调用;(2)在用 户改变屏幕方向时,此方法会被调用;(3)在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调 用。第一种情况我们无法保证什么时候发生,系统根据资源紧张程度去调度;第二种是屏幕翻转方向时,系统先销毁当前的Activity,然后再重建一个新 的,调用此方法时,我们可以保存一些临时数据;第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态。 onSaveInstanceState的调用顺序是在onPause之前。

4. 3.onRestoreInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,然后用户又回到了此 Activity,此方法会被调用;(2)在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。 onRestoreInstanceState的调用顺序是在onStart之后。

。。。。。。。。。。。。省略

Logcat是干吗用的?

日志猫,是Android中一个命令行工具,可以用于得到程序的log信息。

如何实现界面的跳转?

跳转时如何携带数据?

将数据直接封装在intent中或者数据封装在bundle,将bundle对象封装在intent中。

需要在源activity中使用intent.putExtra()方法传出数据、在对应activity中使用intent.get**Extra()方法接收数据。

LinearLayout的特点是什么?

LinearLayout是线性布局控件,它包含的子控件将以横向或竖向的方式排列,按照相对位置来排列所有的widgets或者其他的containers,超过边界时,某些控件将缺失或消失。

RelativeLayout的特点是什么?

RelativeLayout是相对布局控件,是一个允许子视图相对于其他兄弟视图或是父视图显示的视图组。每个视图的位置能够指定它相对于兄弟或是父视图(这里是指相对布局容器)的位置。

ViewGroupView有关系吗?

何时使用include包含公共的界面,何时选择自定义控件?

在一个项目中我们可能会需要用到相同的布局设计,如果都写在一个xml文件中,代码显得很冗余,并且可读性也很差,所以我们可以把相同布局的代码单独写成一个模块,然后用到的时候可以通过<include/> 标签来重用layout代码。当系统自带的空间无法满足我们的需求,可以选择自定义控件。

ListView控件使用及其优化是怎样的?

ListView控件是一个列表控件,它继承自AdapterView类,ListView的布局是由一条一条的Item组成的,这每一个Item又是一个View。ListView控件的特点是每一个列表项(item)独占一行,每一行的布局都是相同的,其中显示的内容和行布局分离。

优化:a、重用了convertView,很大程度上的减少了内存的消耗。通过判断convertView是否为null,是的话就需要产生一个视图出来,然后给这个视图数据,最后将这个视图返回给底层,呈献给用户。

b、通常有一个内部类classViewHolder,这个ViewHolder,用来标识view中一些控件,方便进行一些事件相应操作的设置,比如 onClick等等,这样可以不用每次都要findViewById了,减少了性能的消耗。同时重用了convertView,很大程度上的减少了内存的消耗

c、把要获取的数据先加载到内存里面,再处理数据的时候,直接从内存中获取。

d数据分页加载

Adapter起到的作用是什么?

  adapter使数据绑定到控件变得更加简单和灵活。

SharedPreferences存储方式的特点是什么?最终生成的文件是什么格式?

SharedPreferences存储方式,它是Android提供的用来存储一些简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入。 除SQLite数据库外,另一种常用的数据存储方式,其本质就是一个xml文件,常用于存储较简单的参数设置。用来存储 “键-值”格式的数据。

数据库存储用的是什么?Cursor是什么?如果不会SQL语句怎么办?

1、 SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据库存储方式。Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。       

2、 Cursor是每行的集合(1)使用moveToFirst()定位第一行。(2)你必须知道每一列的名称。(3)你必须知道每一列的数据类型。(4)Cursor 是一个随机的数据源。(5)所有的数据都是通过下标取得。

3、 还可以用这三种存储方式SharePreference、File、ContentProvider、网络。

从网络中获取数据的思路是怎样的?

首先需要获取到HttpURLConnection的实例,一般只需new出一个URL对象,并传入目标的网络地址,然后调用一下openConnection()方法即可。得到了HttpURLConnection的实例之后,我们可以设置一下HTTP请求所使用的方法。常用的方法主要有两个,GET和POST。GET表示希望从服务器那里获取数据,而POST则表示希望提交数据给服务器。接下来就可以进行一些自由的定制了,比如设置连接超时、读取超时的毫秒数,以及服务器希望得到的一些消息头等。之后再调用getInputStream()方法就可以获取到服务器返回的输入流了,剩下的任务就是对输入流进行读。之后再调用getInputStream()方法就可以获取到服务器返回的输入流了,剩下的任务就是对输入流进行读取。最后可以调用 disconnect()方法将这个HTTP连接关闭掉

XML解析技术有哪些?

 (1)DOM解析器(2)SAX解析器(3)PULL解析器

JSON解析又是什么?

JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度。         

XML解析和JSON解析各自的优缺点是什么?

1、两者的数据可读性基本相同,都拥有同样丰富的解析手段

2、json的数据体积更小,与JS的交互更加方便,解析速度更快

  3、xml对数据的描述性更好

多线程创建的方式有哪些?

1、通过扩展Thread类来创建多线程

2、通过实现Runnable接口来创建多线程

3、通过实现Runnable接口来实现线程间的资源共享

Handler的作用是什么?

与其他线程协同工作,接收其他线程的消息并通过接收到的消息更新主UI线程的内容。也就是说handler保存了两个队列,一个消息队列,一个runnable队列,handler负责顺序一个一个执行两个队列里需要处理的元素

如何创建一个ServiceServiceActivity是在同一个进程中吗?

   情况1:当Acitivity和Service处于同一个Application和进程时,通过继承Binder类来实现。

情况2:跨进程通讯,使用AIDL;

 

一般来说:同一个包内的activity和service,如果service没有设定属性Android:process=":remote" 的话,service会和activity跑在同一个进程中,由于一个进程只有一个UI线程,所以,service和acitivity就是在同一个线程里面的。android:process=":remote"值得注意他的用法!!!如果Activity想访问service中的对象或方法,如果service设定属性android:process=":remote",那么就是跨进程访问,跨进程访问容易出现意想不到的问题,还是慎重给 service设定属性android:process=":remote"

如果想要读取手机通讯录中的联系人信息怎么办?

1、  manifest中权限配置,即读取和写入联系人信息的权限

2、  读取主要方法:

/*
     * 读取联系人的信息
     */
    public void testReadAllContacts() {
        Cursor cursor = this.getContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, 
                 null, null, null, null);
        int contactIdIndex = 0;
        int nameIndex = 0;
        
        if(cursor.getCount() > 0) {
            contactIdIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID);
            nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        }
        while(cursor.moveToNext()) {
            String contactId = cursor.getString(contactIdIndex);
            String name = cursor.getString(nameIndex);
            Log.i(TAG, contactId);
            Log.i(TAG, name);
            
            /*
             * 查找该联系人的phone信息
             */
            Cursor phones = this.getContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
                    null, 
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, 
                    null, null);
            int phoneIndex = 0;
            if(phones.getCount() > 0) {
                phoneIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            }
            while(phones.moveToNext()) {
                String phoneNumber = phones.getString(phoneIndex);
                Log.i(TAG, phoneNumber);
            }
            
            /*
             * 查找该联系人的email信息
             */
            Cursor emails = this.getContext().getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
                    null, 
                    ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=" + contactId, 
                    null, null);
            int emailIndex = 0;
            if(emails.getCount() > 0) {
                emailIndex = emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
            }
            while(emails.moveToNext()) {
                String email = emails.getString(emailIndex);
                Log.i(TAG, email);
            }
            
        }
    }

 

如何进行单元测试?单元测试的目的是什么?

测试:activity继承InstrumentationTestCase,需要新建一个AndroidTestProject,而测试逻辑继承AndroidTestCase则是在原项目中进行,可以将测试代码统一放到一个yourpackage.test包下。

目的:  Android单元测试,主要目的是为了保证复杂逻辑是否正常正确,以及依据TDD的原则,测试先于编码,理清代码编写的思路。 

如果项目运行报NullPointerException,你会如何做?

debug看代码在哪里地方报的空指针异常

如果项目运行报ActivityNotFoundException,你会怎么做?

首先查看有没有在manifest.xml中注册了此activity

如果项目运行报PermissionDennied,你会怎么做?

首先查看有没有在manifest.xml中有没有注册此权限

 

 

0 0