周康的博客

一蓑烟雨任平生


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 简历

NFC标签的读写

发表于 2017-01-19 | 分类于 Android

概述

现在市面上所售的Android手机几乎都支持NFC功能,作为开发者有必要对其进行一番了解,NFC技术是一种短距高频的无线电技术,主要用于IOT领域。NFC在Android上,是从API9才开始支持的,但是到了API14 Google才对NFC大力开发,所以等到了API15的时候,NFC的传输速度就得到了很大的加强,所以最小api最好设置为14。它有三种模式数据交互形式:

  1. 读卡器模式(Reader/Witer Mode)
  2. 仿真卡模式(Card Emulation Mode)公交刷卡所用的方式
  3. 点对点模式(P2P Mode)共享数据所用的方式
    今天主要实现读卡器模式。
阅读全文 »

Http网络基础

发表于 2016-12-10 | 分类于 网络基础

OSI 的七层模型

阅读全文 »

Activity与Service之间的交互

发表于 2016-11-18 | 分类于 Android

概述

在我经历的所有的面试当中几乎都会遇到这样一道面试题:Activity与Service之间是如何交互的。这个问题看上去很简单,实际上它确实也简单(神转折)。主要是因为面试官问的多了,简单归简单,但我觉得挺重要的。特意写一篇文章记录一下。

交互方式

Acticity与Service传递参数方式有很多种,例如:

  1. 把变量声明为静态的,通过类名获取参数。
  2. 利用Intent传递
  3. 利用广播的方式传递。
  4. 还有通过存储方式(Shareperferrence,File、sqlie等)来传递。
  5. 重写ServiceConnetion。(重点)

我想面试官问你这个问题的主要目的就是看你会不会第五个方法。前面四个虽说能传递参数,但其实都不可取。只有第五个才是我们项目中经常使用的方法。
现在假设一个场景:在Service中下载文件,下载的进度要回调给Activity。

我们先新建一个接口:

1
2
3
4
5
6
/**
*回调进度接口
*/
public interface OnProgressListener {
void onProgress(int progress);
}

再新建一个Service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public class MsgService extends Service {
/**
* 进度条的最大值
*/
public static final int MAX_PROGRESS = 100;
/**
* 进度条的进度值
*/
private int progress = 0;
/**
* 增加get()方法,供Activity调用
* @return 下载进度
*/
public int getProgress() {
return progress;
}
/**
*回调进度接口
*/
private OnProgressListener onProgressListener;
/**
* 注册回调接口的方法,供外部调用
* @param onProgressListener
*/
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}
/**
* 模拟下载文件任务,每秒钟更新一次
*/
public void startDownLoad(){
new Thread(new Runnable() {
@Override
public void run() {
while(progress < MAX_PROGRESS){
progress += 5;
//进度发生变化通知调用方
if(onProgressListener != null){
onProgressListener.onProgress(progress);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
/**
* 返回一个Binder对象
*/
@Override
public IBinder onBind(Intent intent) {
return new MsgBinder();
}
public class MsgBinder extends Binder{
/**
* 获取当前Service的实例
* @return
*/
public MsgService getService(){
return MsgService.this;
}
}
}

在Activity中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public class MainActivity extends Activity {
private MsgService msgService;
private ProgressBar mProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定Service
Intent intent = new Intent("com.example.communication.MSG_ACTION");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
Button mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//开始下载
msgService.startDownLoad();
}
});
}
/**
*创建ServiceConnection
*/
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//返回一个MsgService对象
msgService = ((MsgService.MsgBinder)service).getService();
//注册回调接口来接收下载进度的变化
msgService.setOnProgressListener(new OnProgressListener() {
@Override
public void onProgress(int progress) {
mProgressBar.setProgress(progress);
}
});
}
};
/**
*解除绑定
*/
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}

这里需要注意开启Service只能用binService进行绑定,不能用startService。因为调用bindService (Intent service, ServiceConnection conn, int flags)方法,得到Service对象的一个引用,这样Activity可以直接调用到Service中的方法。

这里再顺带说一下利用广播发送消息,其优势稍稍弱于ServiceConnection。
首先要在Activity中注册广播,在定义广播接收器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//动态注册广播接收器
private void setBroadcast(){
msgReceiver = new MsgReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.communication.RECEIVER"); //设置Action
registerReceiver(msgReceiver, intentFilter);
}
/**
* 广播接收器
* @author len
*
*/
public class MsgReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//拿到进度,更新UI
int progress = intent.getIntExtra("progress", 0);
mProgressBar.setProgress(progress);
}
}

在Service中,每当下载进度改变时都要发送广播,让Acticty接受,Action要对应Activity中的Action

1
2
3
4
Intent intent = new Intent("com.example.communication.RECEIVER");
//发送Action为com.example.communication.RECEIVER的广播
intent.putExtra("progress", progress);
sendBroadcast(intent);

利用广播适合用于向多个Activity发送相同的消息,单个Activity的话还是用ServiceConnetion更好一些。

代理设计模式

发表于 2016-11-13 | 分类于 Java

概述

设计模式体现出的是一种编程思想,偶尔跟人交流(装逼)时,都喜欢把编程形容为一门艺术,而艺术往往包含了思想、灵魂甚至是哲学的元素在里面。所以很多人觉得程序员闷骚,怪异和宅等。其实细想一下,这也不就是艺术家的特性嘛。朴素的唯物主义认为世界是由金木水火土组成的,而对于程序员来说,世间皆由对象组成的,金木水火土间接或直接的构成对象,我是不是可以认为,程序员都属于唯物主义者的艺术家呢。哈哈哈哈哈哈哈哈…装逼到此。
今天讲的代理设计模式是程序中很常用且很重要的一种设计模式。我们常使用的框架如Retrofit、 Xutils等都使用了代理设计模式,定义:为其他对象提供一种代理,以控制对这个对象的访问。通过调用代理,来间接的调用实际的对象。它分为静态代理和动态代理。举个例子,假如我们要去银行办卡,但是我们自己能直接办卡吗,这肯定是不能的,卡是由银行的工作人员来帮我们办的。我们有办卡的需求,而工作人员就是代理对象,间接的帮我们完成需求。

阅读全文 »

关于Handle的几个问题

发表于 2016-09-16 | 分类于 Android

提出问题

现在这里列出几个问题,思考一下:

  1. Handler的作用
  2. 为什么Android中要设计为只能在UI线程中去更新UI呢?
  3. 说说Handler、Looper MessageQueue之间的关系
  4. 主线程往子线程发消息
  5. 子线程中可以使用Handler吗?
  6. 可以在非主线程中更新UI吗?
  7. 使用Handle要注意什么(会引发什么问题)?
    阅读全文 »

View的绘制流程

发表于 2016-09-15 | 分类于 Android

概述

关于View的绘制我阅读过的所有博文都很长,一篇文章看下来至少要花两三个小时,才能看个大概,包括其中的源码分析等。今天这篇文章主要是针对View的绘制做下大概的汇总,不会很详细,网上关于View的绘制流程详细介绍有很多,大家自行百度吧。这篇文章的目的是假如有人问你的时候,比如面试官,你能用简单的话语介绍给他听,尽管是简答,但是该有的还是要有。

阅读全文 »

ScrollView镶嵌ListView问题原因分析

发表于 2016-07-23 | 分类于 Android

概述

ScrollView内镶嵌ListView会出现显示不全(只显示一个Item)的问题,这里我们要回答具体原因和解决方案。

阅读全文 »

Activity的启动流程

发表于 2016-07-18 | 分类于 Android

概述

昨天已经差不多写好这篇博文了,只剩下最后的总结没写,想着今早再补上去,结果忘记保存了(写的那么长竟然也能忘记保存,我挺佩服自己的)。。。按理说没保存也能在缓存里面找回来的,可是今早开电脑的时候手贱点开了360清理了一下,现在心里可苦可苦了。还好只是篇文章,不是什么重要的文件,血的教训,标记一下。今天重新写过。
关于Activity的启动流程我也是学习了挺久的了,看了很多文章。网上也有大神觉得这个很简单,不过对于我来讲还是挺难理解的,因为里面涉及到了IPC(进程间的通讯)和binder的原理,对于这块其实我还不很熟,所以先学习了IPC和binder再来研究Activity的启动流程,学习嘛,一定要学到关键的地方,要了解原理,不然很快就忘了。现在开始吧

阅读全文 »

HashMap排序

发表于 2016-06-30 | 分类于 Java

概述

面试的时候遇到过这样一道算法题,已知HashMap map,User类中有int age,String name属性。请根据User中的age进行降序排序。我们知道HashMap是没有顺序的,这里应该怎么处理呢?回来后想想应该用LinkedHashMap,LinkedHashMap是有顺序的而且是继承HashMap。


阅读全文 »

ListView的优化

发表于 2016-03-25 | 分类于 Android

概述

ListView是我最初学Android时最常用的几个控件之一了,那时候根本不知道什么是自定义View,什么是优化。后来看了别人写的代码才发现在getView里面还能有这样的操作呢!ListView的优化是我每次去面试必问的几道面试题之一。当然内容也很简单,今天不细讲,就大概汇总一下。

ListView的优化方案

  1. 复用converView
    目的不用每次都findViewbyid

  2. 定义静态内部类ViewHolder
    为了避免对外部类(外部类很可能是Activity)对象的引用,那么最好将内部类声明为static的(非必须的)。

  3. 尽可能减少在getView中的逻辑判断

  4. Item布局优化
    减少布局镶嵌,减少背景覆盖(重复渲染)

  5. 滑动时停止加载图片

  6. 使用分页

  7. 数据类型考虑使用弱引用

  8. 缓存

1234
周 康

周 康

爱学习的好孩子

32 日志
5 分类
17 标签
E-Mail 新浪微博 Skype
© 2018 周 康