Android面试一天一题(1Day)
写在前面
该博客思路源于在简书看到goeasyway博主写的Android面试一天一题系列,无copy之意,仅为让自己总结知识点,成长一点点。先感谢各位大神的无私分享~!
关于题目,大部分则出自AndroidInterview-Q-A和LearningNotes,当然既然是Android面试,主要是Android部分,Java基础之后再写。
IntentService作用是什么,AIDL解决了什么问题 — 小米
想知道IntentService的作用,当然需要先了解何为IntentService。
IntentService
官方解释是这样说的:
IntentService是一个基于Service的子类,其能够根据需求处理异步请求(作为Intent一样来表示)。客户端通过startService(Intent)发送异步请求调用;服务作为需要而开始,控制每个Intent来转向使用一个工作线程,并且当工作完成后自己会停止。
这个
工作队列处理器部分通常用于从应用的主线程卸下任务IntentService类纯在为了简化这个部分和考虑到了mechanics。为了使用它,扩展IntentService和实现onHandleIntent(Intent)。IntentService会收到Intents,启动一个工作线程和恰当地停止服务。所有请求被耽搁工作线程控制 — 他们可能只需要(切不会阻塞应用主线程),但每次只处理一个请求。
先抛开官方解释不说,其实我们应该想想为什么有了Service还需要一个IntentService呢?这里就引出Service与IntentService之间的区别,那么两者是否应该有联系,区别又是什么呢?考虑问题时我们应该往深度和广度去探索,当然别太深无法自拔最后自己都不知道想要了解什么问题。所以接下来的几个问题:
Service的弊端?为什么会出现IntentService,Service和IntentService的区别?
如果说Service是依附于主线程的,也就是说不能进行耗时操作,而继承于它的子类IntentService中新增了哪些代码呢,这就可以从源码入手了,下面是IntentService的几个重要元素:
public abstract class IntentService extends Service {
// Looper可以知道需要与handler的套用,进行MessageQueue的资源存放和索取
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
// ... 代码省略 ...
// 实际上也是通过Handler的机制来实现耗时操作
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
// ... 代码省略 ...
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
// 从上面实例化的线程中获取Looper,然后再传入ServiceHandler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
// ... 代码省略 ...
/**
* This method is invoked on the worker thread with a request to process.
* Only one Intent is processed at a time, but the processing happens on a
* worker thread that runs independently from other application logic.
* So, if this code takes a long time, it will hold up other requests to
* the same IntentService, but it will not hold up anything else.
* When all requests have been handled, the IntentService stops itself,
* so you should not call {@link #stopSelf}.
*
* @param intent The value passed to {@link
* android.content.Context#startService(Intent)}.
*/
@WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
注意onHandleIntent方法的注释:
该方法可以为唤起一个工作线程,而每次只能处理一个Intent,但是这个过程发生在工作线程中,并且运行在一个独立于其他的应用逻辑中,因此如果这部分代码会花一些时间的话,就会先拦截别的请求对于同一个IntentService,但不会拦截除此之外的事件。一旦所有请求都被处理了以后,IntentService会自动停止,你不需要调用stopSelf。
啰嗦一大堆,说白了IntentService就是为了实现让Service能够进行耗时操作的功能。
IntentService的用法
光知道概念和原理,但是不会用怎么行呢,我们以一个简单的Demo来进行示例,首先创建一个MainActivity负责事件开始,点击onClick的时候启动IntentService:
public class MainActivity extends AppCompatActivity {
private boolean serviceRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView serviceStates = (TextView) findViewById(R.id.tv_service_states);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent serviceIntent = new Intent(MainActivity.this, CustomIntentService.class);
serviceIntent.putExtra("sleep_flag", true);
if (!serviceRunning) {
startService(serviceIntent);
serviceStates.setText("Service is running...");
} else {
stopService(serviceIntent);
serviceStates.setText("Service is stop...");
}
serviceRunning = !serviceRunning;
}
});
}
}
public class CustomIntentService extends IntentService {
public static final String TAG = CustomIntentService.class.getSimpleName();
public CustomIntentService() {
super("CustomIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG, " onHandleIntent====> ");
boolean flag = intent.getBooleanExtra("sleep_flag", false);
Log.e(TAG, " onHandleIntent flag ====> " + flag);
}
@Override
public void onCreate() {
Log.e(TAG, " onCreate ====> executed ");
super.onCreate();
}
@Override
public void onDestroy() {
Log.e(TAG, " onDestroy ====> executed ");
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, " onStartCommand ====> executed ");
boolean flag = intent.getBooleanExtra("sleep_flag", false);
Log.e(TAG, " onStartCommand flag ====> " + flag);
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, " onBind ====> executed ");
return super.onBind(intent);
}
@Override
public boolean onUnbind(Intent intent) {
Log.e(TAG, " onUnbind ====> executed ");
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
Log.e(TAG, " onRebind ====> executed ");
super.onRebind(intent);
}
}
因为我在Intent中传递了一个boolean值作为标记,可以在下面的执行结果中看到IntentService方法的执行顺序:
E/CustomIntentService: onCreate ====> executed
E/CustomIntentService: onStartCommand ====> executed
E/CustomIntentService: onStartCommand flag ====> true
E/CustomIntentService: onHandleIntent====>
E/CustomIntentService: onHandleIntent flag ====> true
E/CustomIntentService: onDestroy ====> executed
当我在onHandleIntent()中使线程睡眠10s时,连续点击两次启动Button,可以看到并没有出现Service中ANR的问题,过了一会sleeping end才结束,因为IntentService通过新的子线程来进行耗时操作,从而不会影响主线程的业务逻辑。
@Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG, " onHandleIntent====> ");
boolean flag = intent.getBooleanExtra("sleep_flag", false);
Log.e(TAG, " onHandleIntent flag ====> " + flag);
Log.e(TAG, " onHandleIntent====> sleeping start");
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG, " onHandleIntent====> sleeping end");
}
// 第一次点击
E/CustomIntentService: onCreate ====> executed
E/CustomIntentService: onStartCommand ====> executed
E/CustomIntentService: onStartCommand flag ====> true
E/CustomIntentService: onHandleIntent====>
E/CustomIntentService: onHandleIntent flag ====> true
E/CustomIntentService: onHandleIntent====> sleeping start
E/CustomIntentService: onDestroy ====> executed
// 第二次点击
E/CustomIntentService: onCreate ====> executed
E/CustomIntentService: onStartCommand ====> executed
E/CustomIntentService: onStartCommand flag ====> true
E/CustomIntentService: onHandleIntent====>
E/CustomIntentService: onHandleIntent flag ====> true
E/CustomIntentService: onHandleIntent====> sleeping start
E/CustomIntentService: onDestroy ====> executed
// sleep结束
E/CustomIntentService: onHandleIntent====> sleeping end
E/CustomIntentService: onHandleIntent====> sleeping end
Android面试一天一题(1Day)的更多相关文章
- 2021大厂Android面试高频100题最新汇总(附答案详解)
前言 现在越来越多的人应聘工作时都得先刷个几十百来道题,不刷题感觉都过不了面试. 无论是前后端.移动开发,好像都得刷题,这么多人通过刷题过了面试,说明刷题对于找工作还是有帮助的. 不过这其中有一个问题 ...
- android 面试准备基础题
1. 请描述下Activity的生命周期. 必调用的三个方法:onCreate() --> onStart() --> onResume(),用AAA表示 )父Activity启动子 ...
- Android面试优雅地介绍自己的项目
本文转载:m.blog.csdn.net/iamsamzhang/article/details/51916584 先说句题外话,很多公司16年秋招的内推已经开始啦,我目前知道的在北京有网易.百度和微 ...
- 2020年最新阿里、字节、腾讯、京东等一线大厂高频面试(Android岗)真题合集,面试轻松无压力
本文涵盖了阿里巴巴.腾讯.字节跳动.京东.华为等大厂的Android面试真题,不管你是要面试大厂还是普通的互联网公司,这些面试题对你肯定是有帮助的,毕竟大厂一定是行发展的标杆,很多公司的面试官同样会研 ...
- Android开发如何准备技术面试(含Android面试押题)
今年毋庸置疑是找工作的寒冬,每一个出来找工作的同学都是值得尊敬的.现在找工作,虽然略难,但是反过来看也会逼迫我们成为更加优秀的自己. 但是不管是旺季还是寒冬,有一些优秀的同学找工作还是挺顺利的.所以说 ...
- Android面试总结 (转)
1. 下列哪些语句关于内存回收的说明是正确的? (b) A. 程序员必须创建一个线程来释放内存 B. 内存回收程序负责释放无用内存 C. 内存回收程序允许程序员直接释放内存 D. 内存回收程序可以在指 ...
- 【Android面试】Android面试题集锦 (陆续更新)(最新2012-6-18) eoe上看到的
===============eoeAndroid社区推荐:======================= 1.Android开发新浪面试题[开发者必看哦]下载地址 http://www.eoeand ...
- Android面试题目及其答案
转自:http://blog.csdn.net/wwj_748/article/details/8868640 Android面试题目及其答案 1.Android dvm的进程和Linux的进程, 应 ...
- Android面试题目2
1. 请描述下Activity的声明周期. onCreate->onStart->onRemuse->onPause->onStop->onRestart->onD ...
随机推荐
- 微软Azure 经典模式下创建内部负载均衡(ILB)
微软Azure 经典模式下创建内部负载均衡(ILB) 使用之前一定要注意自己的Azure的模式,老版的为cloud service模式,新版为ARM模式(资源组模式) 本文适用于cloud servi ...
- System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。
在NHibernate数据库查询中出现了这个错误,由于是数据库是mysql的,当定义的字段为char(36)的时候就会出现这个错误. [解决方法] 将char(36) 改成varchar(40)就行了 ...
- 如何利用pt-online-schema-change进行MySQL表的主键变更
业务运行一段时间,发现原来的主键设置并不合理,这个时候,想变更主键.这种需求在实际生产中还是蛮多的. 下面,看看pt-online-schema-change解决这类问题的处理方式. 首先,创建一张测 ...
- 【热门技术】EventBus 3.0,让事件订阅更简单,从此告别组件消息传递烦恼~
一.写在前面 还在为时间接收而烦恼吗?还在为各种组件间的消息传递烦恼吗?EventBus 3.0,专注于android的发布.订阅事件总线,让各组件间的消息传递更简单!完美替代Intent,Handl ...
- Web安全相关(三):开放重定向(Open Redirection)
简介 那些通过请求(如查询字符串和表单数据)指定重定向URL的Web程序可能会被篡改,而把用户重定向到外部的恶意URL.这种篡改就被称为开发重定向攻击. 场景分析 假设有一个正规网站http:// ...
- 【SAP业务模式】之ICS(四):组织单元的配置
SAP的ICS业务后台配置主要有以下几个配置点: 1.组织单元的配置(公司代码.销售组织.工厂.采购组织等): 2.主数据的部分: 3.订单和开票的定价过程: 4.开票输出类型: 5.公司间发票的配置 ...
- Atitit.项目修改补丁打包工具 使用说明
Atitit.项目修改补丁打包工具 使用说明 1.1. 打包工具已经在群里面.打包工具.bat1 1.2. 使用方法:放在项目主目录下,执行即可1 1.3. 打包工具的原理以及要打包的项目列表1 1. ...
- 了解 ARDUINO 101* 平台
原文链接 简介 作为一名物联网 (IoT) 开发人员,您需要根据项目的不同需求,选择最适合的平台来构建应用. 了解不同平台的功能至关重要. 本文第一部分比较了 Arduino 101 平台和 Ardu ...
- charles工具抓包教程(http跟https)
1.下载charles 可以去charles官网下载,下载地址:http://www.charlesproxy.com/download/ 根据自己的操作系统下载对应的版本,然后进行安装,然后打 ...
- vue2.0构建淘票票webapp
项目描述 之前一直用vue1.x写项目,最近为了过渡到vue2.0,特易用vue2.0栈仿写了淘票票页面,而且加入了express作为后台服务. 前端技术栈:vue2.0 + vue-router + ...