Android--超强面试总结<不断更新中.......>

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tiem_erhu/article/details/52800991

1-:安卓中常用的布局:
开发中,共有五种布局:分别是:FrameLayout(帧布局),LinearLayout
(线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局),TableLayout(表格布局)

2-:Activity的生命周期:

Activity launched--onCreate()--onStart()<onRestart>--onResume()--Activity running--onPause()
--onStop()--onDestroy()--Activity shut down

这里写图片描述
3-:Fragment的生命周期:

Fragment is added--onAttach()--onCreate()--onCreateView()--onActivityCreated()--
onStart()--onResume()--Fragment is active--onPause()--onStop()--onDestroyView()
--onDestroy()--onDetach()--Fragment is destroyed

这里写图片描述
4-:简述Activity在不同运行情况下的生命周期执行过程:
-1:打开一个Activity实例时,会执行:

onCreate()--onStart()--onResume()

然后达到运行状态
当Running状态被覆盖时<打开新的Activity或者锁屏>,执行onPause()
<该方法执行时,Activity运行状态暂停,在此状态通常用于提交未保存的更改到持久化数据,停止动画等,此Activity还是“活的“,保持所有的状态和成员信息以及连接窗口管理器>

接下来,不同的情况:


1-:返回到该Activity时,调用onResume,然后Running;
2-:用户回到桌面或进入其他的Activity,会调用onStop进入停止状态<根据task>
3-:系统内存不足,拥有更高权限的应用需要内存时,那么此Activity 的进程就可能被系统回收<Activity的状态为onStop和onStart可能会被回收>

如果用户返回到状态为onStop状态的Activity<此时需要显示>,则会执行:

onRestart()--onStart()--onResume()

然后重新达到运行状态

-2:在Activity调用finish()或被系统杀死之前会调用onDestroy释放资源
-3:Activity中三个循环生命周期的嵌套:
● activity的完整生存期会在 onCreate() 调用和 onDestroy() 调用之间发生。 
● activity的可见生存期会在 onStart() 调用和 onStop() 调用之间发生。系统会在activity的整个生存期内多次调用 onStart() 和onStop(), 因为activity可能会在显示和隐藏之间不断地来回切换。 
● activity的前后台切换会在 onResume() 调用和 onPause() 之间发生。
-4:Activity中被回收的信息和状态保存以及恢复:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if(savedInstanceState!=null){ //判断是否有以前的保存状态信息
             savedInstanceState.get("Key"); 
             }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
   @Override
protected void onSaveInstanceState(Bundle outState) {
     //可能被回收内存前保存状态和信息,
       Bundle data = new Bundle(); 
       data.putString("key", "last words before be kill");
       outState.putAll(data);
    super.onSaveInstanceState(outState);
}
   @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
       if(savedInstanceState!=null){ //判断是否有以前的保存状态信息
             savedInstanceState.get("Key"); 
             }
    super.onRestoreInstanceState(savedInstanceState);
}
}
onSaveInstanceState(Bundle outState)

在activity可能被回收之前调用,用来保存自己的状态和信息,以便回收后重建时恢复数据(在onCreate(
或onRestoreInstanceState()中恢复)。旋转屏幕重建activity会调用该方法,但其他情况在onRause()和onStop()状态的activity不一定会调用 ;也就是说,系统灵活的来决定调不调用该方法,但是如果要调用就一定发生在onStop方法之前,但并不保证发生在onPause的前面还是后面。

onRestoreInstanceState(Bundle savedInstanceState)

方法在onStart 和 onPostCreate之间调用,在onCreate中也可以状态恢复,但有时候需要所有布局初始化完成后再恢复状态。

  onPostCreate

一般不实现这个方法,当程序的代码开始运行时,它调用系统做最后的初始化工作。

-5:横竖屏切换:
1-:未在代码中或者清单文件中设置方向,表明此可以切换:

可以看到会先调用onSaveInstanceState来保存一些状态,然后销毁此activity,即调用onPause()
--onStop()--onDestroy();然后重新新建此activity,即调用onCreate()--onStart()--onRestoreInstanceState()<恢复状态以及一些信息>--onResume()

2-:清单文件中,对此activity设置android:configChanges=” xxxxxx”:

 可以看到会调用onConfigurationChanged(),没有activity销毁重建的过程。

5-:简述Fragment在不同运行情况下的生命周期执行过程:
-1: 当一个fragment被创建的时候,它会经历以下状态.
● onAttach()
● onCreate()
● onCreateView()
● onActivityCreated()
-2:当这个fragment对用户可见的时候,它会经历以下状态。
● onStart()
● onResume()
-3: 当这个fragment进入“后台模式”的时候,它会经历以下状态。
● onPause()
● onStop()
-4:当这个fragment被销毁了(或者持有它的activity被销毁了),它会经历以下状态。
● onPause()
● onStop()
● onDestroyView()
● onDestroy()
● onDetach()
-5:就像activitiy一样,在以下的状态中,可以使用Bundle对象保存一个fragment的对象。
● onCreate()
● onCreateView()
● onActivityCreated()
-6:fragments的大部分状态都和activitiy很相似,但fragment有一些新的状态
● onAttached() —— 当fragment被加入到activity时调用,在这个方法中可以获得所在的activity
● onCreateView() —— 当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout(界面)
● onActivityCreated() —— 当activity的onCreated()方法返回后调用此方法
● onDestroyView() —— 当fragment中的视图被移除的时候,调用这个方法
● onDetach() —— 当fragment和activity分离的时候,调用这个方法
一旦activity进入resumed状态(也就是running状态),你就可以自由地添加和删除fragment了。因此,只有当activity在resumed状态时,fragment的生命周期才能独立的运转,其它时候是依赖于activity的生命周期变化的。

-7:生命周期对照表:
这里写图片描述

6-:安卓设备内,数据存储方式:
-1: SharedPreferences
-2:SQlite
-3:ContentProvider
-4:文件存储
-5:网络交互数据

7-:Uri与Url的区别:
URI,统一资源标识符,用来唯一的标识一个资源。而URL,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。而URN,统一资源命名,是通过名字来标识资源,比如mailto:java-net@java.sun.com。也就是说,URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。

8-:Service启动方式以及生命周期:
-1:被开启的service通过其他组件调用startservice()被创建;
此service可以无限的运行下去,必须调用stopself()或者其他组件调用stopService来停止,当service被停止时,系统会销毁它;
-2:被绑定的service是当其他组件来调用bindservice()来创建;
组件可以通过一个IBinder来与service进行通信,组件可以调用unbindservice来关闭连接,此时,service可以和多个组件进行绑定,当多个组件都接触绑定,系统会销毁它<一个被开启的service仍然可能会被绑定>;

-3:根据图,生命周期分析:
这里写图片描述
  -1:service整体的生命时间是从onCreate()被调用开始,到onDestroy()方法返回为止
  和activity一样,service在onCreate()中进行它的初始化工作,在onDestroy()中释放残留的资源
  比如,一个音乐播放service可以在onCreate()中创建播放音乐的线程,在onDestory()中停止这个线程;
  onCreate() 和 onDestroy()会被所有的service调用,不论service是通过startService()还是bindService()建立;
onCreate()在service创建时被调用,不论是被startservice还是bindservice创建,整个生命周期内只会执行一次;

-2:service积极活动的生命时间(active lifetime)是从onStartCommand() 或onBind()被调用开始,它们各自处理由startService()或 bindService()方法传过来的Intent对象。
  如果service是被开启的,那么它的活动生命周期和整个生命周期一同结束。
  如果service是被绑定的,它们它的活动生命周期是在onUnbind()方法返回后结束。
  注意:尽管一个被开启的service是通过调用 stopSelf() 或 stopService()来停止的,没有一个对应的回调函数与之对应,即没有onStop()回调方法。所以,当调用了停止的方法,除非这个service和客户组件绑定,否则系统将会直接销毁它,onDestory()方法会被调用,并且是这个时候唯一会被调用的回调方法。

-4:此service是被startservice()创建的,当实现onStartCommand()回调方法时,需要显示调用停掉此service

-5:此service被开启并且可以被绑定的时,那么当系统调用 onUnbind()方法时,如果想要在下次客户端绑定的时候接受一个onRebind()的调用(而不是调用 onBind()),你可以选择在 onUnbind()中返回true。onRebind()的返回值为void,但是组件仍然在它的 onServiceConnected()回调方法中得到 IBinder 对象;

<onRebind方法指明:当内存中已有service时,当调用bindService时会调用onRebind(前提是onUnbind必须返回true)>

9-:请用你的语言设计一个网络请求框架:
首先,需要考虑请求方式,常见的就是两种post,get,另外,需要是否有session,token,header;
在网络请求过程中,需要设计几个状态的监听;
-1:onNetError--网络错误,主要应用于当在即将开始进行请求的时候进行是否可以进行联网判断,若是没有网络,则不发送请求,可进行一些操作,比如提示用户网络不可用等;
-2:onSueeess--数据请求成功,主要应用于和服务器交互,状态值state值为200,服务器能接收到相关值处理之后,返回一些数据,通常在这个状态下可以拿到返回值,并进行其他操作,比如,可以根据服务器返回的值对textview,listview进行赋值操作;
-3:onFaile --服务器无响应,主要应用于和服务器交互,状态值state为400,400,500这样的状态值,这样的情况,一般是请求地址错误或者参数错误情况下;
-4:onProgress-- 进度,主要应用于和服务器交互,在大文件请求,上传下载等,可用于提示版本更新时更新进度,加载图片时有一个加载提示框提示加载进度这样的场景;

假设一个场景,一个接口登录接口,当我们输入用户名和密码去请求服务器,正常情况下,服务器会判断这个接口请求的数据是否正确,
若正确,则返回用户的相关信息,不正确的情况下,可以根据返回的错误状态嘛进行相关操作,
比如状态为1是,可以进行提示说用户名或者密码错误,
状态为2 时,用户信息不存在,则提示用户去注册;这种情况下,可以增加一种状态,为onError--用于进行返回信息不是自己预期的情况下一种回调,
比如,可以在服务器返回数据的时候设置一个字断为state设置为0000,当返回的state为0000,则按照我们的预期返回值去执行方法,比如onSueeess;当返回的state为1001时,
则在获取数据时去执行 onError,这种情况下,不是说服务器请求错误,没有返回值,而是说,服务器返回值不是我们预期的,是一种正常条件下的数据错误导致的异常;

1-:若是扩展这个框架,需要在增加几个方法,使用于不同场景
-1:onStart--用于在开始网络请求的请求的时候显示loading,
-2:onFinish--用于在请求完成时disloading,或者进行其他操作;

2-:说一说你见过的其他网络框架中一些状态的名字;
-1:onComplete:请求完成,和onSueeess使用场景类似;

10-:app奔溃时重启应用,需要怎么做:

-1:可以实现uncaughtExceptionHandler接口,用来捕获运行时任意未检测的异常;<复写uncaughtException(Thread t, Throwable e)方法>
-2:在Appliaction进行全局设置,修改清单文件

11-:Http请求方式,区别与联系:
-1:常用的分为Post与Get:
GET方法:
使用GET方法时,查询字符串(键值对)被附加在URL地址后面一起发送到服务器:
/test/demo_form.jsp?name1=value1&name2=value2
特点:
● GET请求能够被缓存
● GET请求会保存在浏览器的浏览记录中
● 以GET请求的URL能够保存为浏览器书签
● GET请求有长度限制<请求参数长度>
● GET请求主要用以获取数据
● 安全性较低
POST方法:
使用POST方法时,查询字符串在POST信息中单独存在,和HTTP请求一起发送到服务器:
POST /test/demo_form.jsp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
特点:
● POST请求不能被缓存下来
● POST请求不会保存在浏览器浏览记录中
● 以POST请求的URL无法保存为浏览器书签
● POST请求一般默认没有长度限制<服务器接收有限制>
● 安全性较高

-2:其他请求方式:
HEAD:与Get请求类似,不同点在于和服务器交互只返回http头部信息,没有页面内容
PUT:上传制定的url描述
DELETE:删除指定的资源
OPTIONS:返回服务器支持的访问方式
CONNECT:转化为透明的tcp/ip隧道的连接请求

12-:简单介绍下安卓中图片的三种缓存策略:
-1:原理:url下载图片时,将图片先缓存到内存缓存中,缓存到强引用中也就是LruCache中。如果强引用中空间不足,就会将较早存储的图片对象驱逐到软引用(softReference)中存储,然后将图片缓存到文件(内部存储外部存储)中;读取图片的时候,先读取内存缓存,判断强引用中是否存在图片,如果强引用中存在,则直接读取,如果强引用中不存在,则判断软引用中是否存在,如果软引用中存在,则将软引用中的图片添加到强引用中并且删除软引用中的数据,如果软引用中不存在,则读取文件存储,如果文件存储不存在,则网络加载。
  下载: 网络–内存–文件
  读取: 内存–强引用–软引用–文件–网络
-2:知识点:软引用可以用来实现内存敏感的高速缓存,能防止内存泄漏,增强程序的健壮性;

13:开发中,怎么做版本的升级?
主要思想就是根据版本来进行更新。第一步,我们会让服务器提供一个接口,请求参数主要为版本号,在每次打开APP的时候,进入到某一页面回去请求接口,第二步,服务器数据库会存一个版本号,每次请求更新接口的时候,服务器会去比对两个版本号是否一致,若一致,则不更新,若不一致,需要更新,则返回的数据中会有一个字段客户端会根据这个约定字段的不同值来进行显示更新或者不显示更新提示框,其中,返回的更新字段中还需要包含新版本的下载地址,新版本的下载地址,是服务器根据新版本的存放位置生成的。其中,强制更新和不强制更新,是和服务器的约定字段,是为了更好的用户的体验,用户可以更新,也可以晚点更新。

14:开发过程中,版本兼容的不同方案:
场景为:
有五个不同的手机,每个手机上都装有不同版本的同一个APP,举例登录接口,第一台手机上第一个版本登录请求需要用户名密码,第二台手机上第二个版本登录请求需要用户名密码以及验证码,第三台手机上第三个版本登录请求只需要手机号以及返回的验证码,第四台手机上第四个版本登录请求是接入的第三方,支持其他方式登录…….
方案如下:
1-:每个版本的不同接口请求地址都不一样,对于不同版本的同一个接口,只要有接口参数改变,就更换请求接口地址
2-:在请求的时候,在每个接口HEAD上动态添加此版本的版本号,服务器可以拿到版本号,然后根据版本号以及请求参数返回的返回值
3-:用一个参数,做标识符,服务器拿到这个标识符参数作为版本区分,可以根据标志符返回不同的值

阅读更多
换一批

没有更多推荐了,返回首页