2016.7.30更新...........................................................................
(66):怎样将一个Activity设置成窗体样式?
通过在Manifest文件中的<activity>标签下设置androif:theme = "@android:style/Theme.Dialog"设置Activity的主题样式即可;
(67):如何安全退出已调用多个Activity的Application?
(1):通常情况下如果是用户想要退出Activity的话,可以通过点击"Back"键实现,但是如果想通过程序退出的话,可以调用finish()方法;
(2):通过发送一条特殊的广播,每个Activity在收到这个广播之后调用finish方法关闭自己即可;
(3):通过一个Activity类型的List在Application里面记录已经打开的Activity,在需要退出的时候遍历List,分别调用每个Activity的finish方法结束Activity就可以了;
(4):可以从当前所在的Activity通过Intent跳转到栈底的那个Activity上面,也就是我们在Manifest中设置的action为MAIN并且category为DEFAULT的Activity上面,并且设置跳转Intent的标志为FLAG_ACTIVITY_CLEAR_TOP,这样的话就会将栈底上面的所有Activity全部都清除掉,我们还需要把这个Activity的启动模式配置为"singleTop",这样会直接调用栈底Activity的onNewIntent方法,在这个方法里面调用finish方法关闭当前Activity就可以了;
(68):Service生命周期
我们通常开启Service有两种方式,既可以通过startService方式,这种方式下可以通过stopService或者stopSelf结束掉Service。不管你调用了多少次startService来开启同一个Service,仅需要调用一次stopService就可以结束掉Service了,原因在于只有第一次调用startService方法才会调用onCreate方法,以后调用startService之后只会多次调用onStartCommand以及onStart方法而已,通过startService开启Service,通过stopService或者stopSelf结束Service的生命周期是:onCreate(只会执行一次)----->onStartCommand(可能会执行多次)----->onStart(可能会执行多次)----->onDestroy(只执行一次);
也可以通过bindService方式,这种Service通常用于我们的跨进程通信中,当我们调用bindService方法之后,会回调服务端的onBind方法,返回我们需要的Binder对象,接着你在客户端就可以使用该Binder对象调用服务端的方法了,如果我们不想绑定该Service了,可以通过unBinderService方法解除绑定,该方法会回调Service的onUnBind方法,同时如果当前Service不再存在绑定的对象的话,会调用其onDestroy方法结束掉Service,通过bindService启动的Service的生命周期为:onCreate----->onBind----->onUnBind----->onDestroy,多次调用bindService的话只会执行一次onBind方法,执行多次unBindService会抛异常;
这两种模式并不是完全分离的,你可以绑定到一个已经调用了startService的Service上面,但是如果想要结束掉两种模式混用的Service,我们需要首先解除掉该Service上面的所有绑定,再调用stopService方法结束掉Service,因为仅仅点击stopService只会停止当前Service,一个Service只有在没有和任何Activity相关联又处于停止状态的情况下才会被销毁;
(69):ListView如何实现分页加载?
(1):为ListView设置滚动监听器setOnScrollListener,该监听器中存在两个方法,滚动状态发生变化的方法onScrollStateChanged和ListView被滚动的时候调用的方法onScroll;
(2):在滚动状态发生变化的方法中存在三种状态:
手指按下移动的状态:SCROLL_STATE_TOUCH_SCROLL;
惯性滑动状态:SCROLL_STATE_FLING;
静止状态:SCROLL_STATE_IDLE;
(3):我们只关心静止状态,关心最后一个可见条目,如果最后一个可见条目就是数据适配器里面的最后一个条目的话,那么这时候就需要加载更多的数据了,每次加载的时候计算出滚动的数量,当滚动数量大于总数量的时候,提示用户无更多数据了;
(70):使用Serializable和Parcelable两种方式实现序列化有什么区别?
使用Serializable和Parcelable都可以完成序列化操作,但是两者适用的场景是不太一样的:
(1):Serializable在序列化的过程中会产生大量的临时变量,会引起较频繁的GC操作,而Parcelable相对来说比较节省内存,因此适用于Android系统中;
(2):Parcelable不能使用在要将数据存储在磁盘上的情况,尽管这时候Serializable效率比较低,但是这种情况下只能他;
(71):Android中如何捕获未捕获的异常?
用户可能在使用应用程序的过程中,应用程序这时候可能会抛出在程序的代码中未捕获的异常,这时候我们应该收集到这些异常信息,并且将其上传至我们的服务器,提醒我们这部分异常信息,及时解决这些异常并且展示给用户一个友好界面,具体实现是:
我们实现一个自定义的Application,叫做MyApplication,这个MyApplication继承了UncaughtExceptionHandler接口,同时我们实现该接口中的onCreate和uncaughtException方法,在onCreate方法里面将我们当前的MyApplication设置为Thread类的默认异常处理Handler,在uncaughtException方法里面开启线程来进行我们的异常收集工作,只要发现有异常发生,我们就会给服务器发出请求,将该异常写入服务端的异常日志文件中,同时在用户界面弹出一个友好提示窗体;
2016.7.31更新...........................................................................(72):Android跨进程通信方式
(1):使用Bundle封装我们想要传递的数据,随后通过Intent发送出去即可,但是有一点需要注意,Bundle里面封装的数据必须是可以序列化的,也就是实现了Serializable或者Parcelable接口的类实例才可以传递;
(2):使用文件共享的方式实现,这种方式适合于数据同步要求不高的进程间通信,并且需要处理好并发读/写问题;
(3):使用Messenger信使,他底层是通过AIDL的方式实现的,具体可以查看他的两个构造方法:Messenger(Handler target)和Messenger(IBinder target);在服务端是通过第一个构造方法创建Messenger对象的,客户端是通过第二个构造方法创建Messenger对象的;
(4):使用Android为我们提供的AIDL文件来进行进程间通信,他的内部是通过Binder实现的;
(5):使用ContentProvider来实现进程间通信,他的内部实现也是Binder,我们可以将一个进程中想要共享给另一个进程的数据封装起来,对外提供一个URI对象,如果某个应用程序想要获取这些数据的话,可以通过ContentProvider使用URI来进行获取,具体就是通过ContentResolver来进行增删改查操作了;
(6):采用Socket通信的方式,当然Socket也可以适用于不同设备之间的通信,因为他是使用套接字(IP+端口号)实现的,但是Binder的话只能适用于同一设备中;
(73):Android源码中的设计模式
(1):单例模式:对于我们经常见到的WindowsManagerService/ActivityManagerService/MediaPlayService都是在我们系统启动的时候注册到系统的ServiceManager服务列表中的,他们在整个系统中都是唯一的;还有我们的Application上下文在系统中也是唯一的;我们通常使用到的LayoutInflater加载布局的类在Android系统中也是单例实现的,在我们虚拟机第一次加载Context实现类ContextImpl的时候,会注册各种ServiceFatcher,这其中就包括了LayoutInflater Service,这些服务是以键值对的方式存放在HashMap里面的,我们在使用的时候只需要通过getService方法通过服务名key获取就可以了,避免了这些对象的重复创建;
(2):工厂模式:工厂方法模式在我们使用容器类ArrayList以及HashMap的时候会用到,他们的父类是Collection,在Collection中存在一个用于生成迭代器的iterator抽象方法,在我们的ArrayList和HashMap中同样会看到实现了iterator方法,并且返回各自的迭代器;
(74):设计模式之工厂模式
工厂模式分为三大类:简单工厂模式、工厂方法模式和抽象工厂模式;
(1):简单工厂模式就是只存在一个工厂来生产产品,具体的生产什么样的产品是根据我们提供的生产产品方法的参数来决定的,不同的参数用于生产不同的产品,这种方法过度依赖工厂里面生产产品的方法,如果这个方法出问题了会导致其他产品也无法生产;
(2):工厂方法模式这种工厂模式为生产产品的工厂抽象出来了一个接口或者抽象类,然后每个用于生成产品的工厂都需要实现这个接口或者类,也就是说每种产品都对应于存在一家工厂来生产产品,解决了简单工厂模式那样只有一家工厂生产产品的问题;
(3):抽象工厂模式是对工厂模式的进一步抽象,当你发现一个接口可以有多种实现的时候,可以考虑使用工厂方法模式实现;但是当你发现一个接口有多种实现方案的时候,可以考虑抽象工厂模式;
对于上述三种工厂模式,比较难理解,我们可以这样理解:
(1):简单工厂模式:对于苹果和小米手机来说,早期只有富士康对他们进行代工生产,会根据是苹果还是小米来进行生产;
(2):工厂方法模式:随着竞争的出现,出来了另一家公司和富士康抢生意,那么这时候苹果选择这家公司来代工,小米选择富士康代工;
(3):抽象工厂模式:随着生产手机的产商越来越多,市场上出现了IOS和Android两大阵营的手机,这时候这两家代工厂将改变策略,不再仅仅只是生产苹果和小米手机了,而是改成一家生产IOS系统系列手机,一家生产Android系统系列手机;
(75):Application类的作用:
如果想要在整个应用中使用全局变量,因为java中不存在全局变量的概念,java中一般使用public修饰的static实现的,但是在Android中这样使用全局变量是不符合Android框架架构的,然而可以使用Application Context代替,重写Application并且重写它里面的onCreate方法,在该方法里面定义我们想要全局使用的变量,因为在Application启动时,系统会创建一个PID,即进程ID,所有的Activity都会在此进程上运行,因此在不同的Activity间便可以共享该变量了;
(76):如何将SQLite数据库(.db文件)与apk文件一起发布
将数据库文件复制到raw文件夹下面,因为在打包发布的时候raw文件夹下面的文件是不会被编译成二进制文件的;
(77):BroadcastReceiver的生命周期