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 ...
随机推荐
- 通过一个demo了解Redux
TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...
- Win10 IIS本地部署网站运行时图片和样式不正常?
后期会在博客首发更新:http://dnt.dkill.net 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 启用关闭win功 ...
- [C#] C# 知识回顾 - 学会处理异常
学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...
- NLP点滴——文本相似度
[TOC] 前言 在自然语言处理过程中,经常会涉及到如何度量两个文本之间的相似性,我们都知道文本是一种高维的语义空间,如何对其进行抽象分解,从而能够站在数学角度去量化其相似性.而有了文本之间相似性的度 ...
- Autofac - 方法注入
方法注入, 其实就是在注册类的时候, 把这个方法也注册进去. 那么在生成实例的时候, 会自动调用这个方法. 其实现的方法, 有两种. 准备工作: public interface IAnimal { ...
- WCF基础
初入职场,开始接触C#,开始接触WCF,那么从头开始学习吧,边学边补充. SOA Service-Oriented Architecture,面向服务架构,粗粒度.开放式.松耦合的服务结构,将应用程序 ...
- 你所能用到的BMP格式介绍
原理篇: 一.编码的意义. 让我们从一个简单的问题开始,-2&-255(中间的操作符表示and的意思)的结果是多少,这个很简单的问题,但是能够写出解答过程的人并不 多.这个看起来和图片格式没有 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 海鑫智圣:物联网漫谈之MQTT协议
什么是MQTT协议 MQTT(消息队列遥测传输协议)是IBM在1999年专门针对物联网等应用场景来制订的轻量级双向消息传输协议,它主要是为了解决物联网上使用到的设备的互相通信的问题,以及这些设备与后端 ...
- Spring Security OAuth2 开发指南
官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...