本篇内容会比较多且零碎,来段舞蹈放松一下先。
-
如何保证service在后台不被kill?
利用的系统广播是Intent.ACTION_TIME_TICK,这个广播每分钟发送一次,我们可以每分钟检查一次Service的运行状态,ActivityManager.getRuningServices()获取所有活动的service,根据名字用equals判断其中没有这个service了,就重新启动Service。
Static可用于修饰在哪些地方?
静态变量,方法,静态内部类,静态代码块,静态导包
-
Fragment 如何实现类似 Activity 栈的压栈和出栈效果的?
Fragment 的事物管理器内部维持了一个双向链表结构,该结构可以记录我们每次 add 的Fragment 和 replace 的 Fragment。
先将上一个fragment压栈,再添加一个新的fragment。
transition.addToBackStack(null)
通过popBackStack可以将压入的栈再次显示出来。
supportFragmentManager.popBackStack()
-
你如何评价Android系统?优缺点?
优点:
开放性:开发的平台允许任何移动终端厂商加入到Android联盟中来,有丰富的软件,硬件。
挣脱运营商的束缚;接入google服务。
缺点:硬件、屏幕太多难适配;安全和隐私,信息被google监视
-
Android cup型号有哪些?
Android 设备的CPU类型(通常称为”ABIs”),目前有7中类型:
mips / mips64: 极少用于手机可以忽略
x86: 平板、模拟器用得比较多。
x86_64: 64位的平板,x86占有量很低。
armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈
armeabi-v7a: ARM v7 目前主流版本,一般市面上的骁龙系列或者麒麟系列的处理器绝大部分都是这种架构
arm64-v8a: 第8代64位处理器,所谓的ARMv8架构,就是在MIPS64架构上增加了ARMv7架构中已经拥有的的TrustZone技术、虚拟化技术及NEON advanced SIMD技术等特性,研发成的。
-
App进程保活
1.白色保活
启动一个前台的Service进程,这样会在系统的通知栏生成一个Notification,用来让用户知道有这样一个app在运行着,哪怕当前的app退到了后台。
2.灰色保活
同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理;它不会在系统通知栏处出现一个Notification,看起来就如同运行着一个后台Service进程一样。
3.使用WorkManager定时任务定时调起App。
-
merge和viewstub使用区别?
merge标签作为跟标签,不会增加view嵌套层数,一般与include一起使用
ViewStub是一个不可见的,实际上是把宽高设置为0的View。ViewStub 标签最大的优点是当你需要时才会加载。
inflate()方法只能调用一次。
android:inflatedId="@+id/panel_import"
<
android:layout="@layout/progress_overlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
-------------------------------------------------
//当你想加载布局时,可以使用下面其中一种方法:
((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
SharedPreferences存储位置和格式是什么?
SharedPreferences 将数据文件写在了手机内存私有的目录中该app的文件夹下。在data\data\程序包名\shared_prefs目录,为shapsname.xml文件。
SharedPreferences sharedPreferences = this.getSharedPreferences("test", MODE_PRIVATE);
其中getSharedPreferences方法第二个参数就是对文件权限的描述。
这个参数有四个可选值:
Activity.MODE_PRIVATE:表示该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
Activity.MODE_APPEND:也是私有数据,新写入的内容会追加到原文件中
Activity.MODE_WORLD_READABLE:表示当前文件可以被其他应用读取
Activity.MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入
SharedPreferences是线程安全的吗?
获取加了同步锁,是线程安全的。
(1)getSharedPreferences()在创建一个SharedPreferences,会先判断是否有对应的xml文件(SharedPreferences存储数据的保存格式),如果存在则会有一个预加载操作,这个操作将把xml文件的内容通过I/O操作和xmlUtil解析后保存在一个map对象中。如果不存在则会创建一个对应的xml。
(2)而在对数据进行读取时,是从内存中该map对象中进行读取;
(3)在使用SharedPreferences保存数据时,主要分为以下两步:把数据先写入内存,写到map集合中、将数据写到硬盘文件保持一致性;由此可以得出,数据在保存的时候,是以key-value的格式保存在xml文件中。
(4)写完数据后,要对写入的数据进行提交保存,主要有以下两种方式:
a. commit():线程安全,性能慢,一般在当前线程完成文件操作,会有返回值;
b. apply():线程不安全,性能高,异步处理I/O操作,一般在singleThreadExecutor中执行,没有返回值
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
synchronized (ContextImpl.class) {
......
final String packageName = getPackageName();
ArrayMap packagePrefs = sSharedPrefs.get(packageName);
if (packagePrefs == null) {
packagePrefs = new ArrayMap();
sSharedPrefs.put(packageName, packagePrefs);
}
......
sp = packagePrefs.get(name);
if (sp == null) {
File prefsFile = getSharedPrefsFile(name);
sp = new SharedPreferencesImpl(prefsFile, mode);
packagePrefs.put(name, sp);
return sp;
}
}
......
return sp;
}
-
App异常退出时,打印日志,重新启动怎么做?
在Application中注册UncaughtExceptionHandler,当发生崩溃会回调uncaughtException()方法,此时在其中做打印日志,重新启动等操作。
public class MyApplication extends Application {
private static MyApplication application;
@Override
public void onCreate() {
super.onCreate();
application = this;
// 程序崩溃时触发线程 以下用来捕获程序崩溃异常
Thread.setDefaultUncaughtExceptionHandler(handler);
}
private Thread.UncaughtExceptionHandler handler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
restartApp(); //发生崩溃异常时,重启应用
}
};
private void restartApp() {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent restartIntent = PendingIntent.getActivity(
application.getApplicationContext(), 0, intent,Intent.FLAG_ACTIVITY_NEW_TASK);
//退出程序
AlarmManager mgr = (AlarmManager)application.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,
restartIntent); // 1秒钟后重启应用
//结束进程之前可以把你程序的注销或者退出代码放在这段代码之前
android.os.Process.killProcess(android.os.Process.myPid());
}
}
-
什么是Android动态布局?
将原本xml布局文件中设置的属性改为在代码中进行相应设置,xml布局属性在代码里有一一对应的方法。
设置位置和大小根据LayoutParams属性来设置,可以设置在父view中的左上右下边距,宽高尺寸。
-
Activity Window View之间是什么关系?
Activity创建出来后,随机会new一个PhoneWindow。当Activity调用setContentView(),会创建一个Decorview,将DecorView作为整个应用窗口的根视图。内部有一个垂直LinearLayout,上面一个view是ActionBar,下面就是id为content的Framelayout,将setContentView()中的view添加到这个FrameLayout中。
-
res/drawable、res/raw、/assets下的区别
res文件夹和assets文件夹区别:
1.res下创建文件,能将ID注册在R文件中,即能通过R.res.xx获取属性。assets需要用径路来使用文件。
2.res下,打包时自动只打包用的上的文件,没用上的文件不打包;assets文件夹里,无论是否在项目中用到,会被原封不动的打包到APK。
3.res/raw,res/assets下图片不会被压缩,res/drawable下会被压缩。