Android存储系统之架构篇

2016年8月2日 由 Creater 没有评论 »

本文讲述Android存储系统的架构与设计,涉及到最为核心的便是MountService和Vold这两个模块以及之间的交互。上一篇文章Android存储系统之源码篇从源码角度介绍相关模块的创建与启动过程,那么本文主要从全局角度把握和剖析Android的存储系统。

MountService:Android Binder服务端,运行在system_server进程,用于跟Vold进行消息通信,比如MountService向Vold发送挂载SD卡的命令,或者接收到来自Vold的外设热插拔事件。MountService作为Binder服务端,那么相应的Binder客户端便是StorageManager,通过binder IPC与MountService交互。

Vold:全称为Volume Daemon,用于管理外部存储设备的Native daemon进程,这是一个非常重要的守护进程,主要由NetlinkManager,VolumeManager,CommandListener这3部分组成。

链接:Android存储系统之架构篇

HTTPS 升级指南

2016年8月1日 由 Creater 没有评论 »

为了升级到 HTTP/2 协议,必须先启用 HTTPS。如果你不了解 HTTPS 协议(学名 TLS 协议),可以参考我以前的文章。
《HTTPS 协议概述》
《图解 HTTPS 协议》
《HTTPS 协议的七个误解》
《HTTPS 协议的延迟有多大?》

参考文献:
http://www.ruanyifeng.com/blog/2016/08/migrate-from-http-to-https.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
http://blog.mimvp.com/2016/01/apache-httpsapache-http-access-go-to-https/

php读写excel相关

2016年7月17日 由 Creater 没有评论 »

PHPExcel – OpenXML – Read, Write and Create Excel documents in PHP – Spreadsheet engine

Project providing a set of classes for the PHP programming language, which allow you to write to and read from different spreadsheet file formats, like Excel (BIFF) .xls, Excel 2007 (OfficeOpenXML) .xlsx, CSV, Libre/OpenOffice Calc .ods, Gnumeric, PDF, HTML, … This project is built around Microsoft’s OpenXML standard and PHP.
Checkout the Features this class set provides, such as setting spreadsheet meta data (author, title, description, …), multiple worksheets, different fonts and font styles, cell borders, fills, gradients, adding images to your spreadsheet, calculating formulas, converting between file types and much, much more!

1.https://github.com/PHPOffice/PHPExcel
2.http://phpexcel.codeplex.com/

fonts.googleapis.com字体加速方案

2016年7月16日 由 Creater 没有评论 »

360网站卫士推出一项字体加速服务,可以免费使用到由360网站卫士CDN加速的字体服务。
修改方法如下:

搜索:fonts.googleapis.com找到这行代码:
比如//fonts.googleapis.com/css?family1=Open+Sans:300italic,400italic,600italic,300,400,600&subset=$subsets”;

把fonts.googleapis.com替换为fonts.useso.com 

通过不同的域名来访问根目录和根目录下的子目录

2016年7月12日 由 Creater 没有评论 »

根目录为www目录,子目录为www\aaa,通过域名www.111.com访问www目录,通过域名www.222.com访问www\aaa目录,操作步骤如下
1)打开apache->httpd.cof(apache2不需要),找到

# Virtual hosts
#Include conf/extra/httpd-vhosts.conf
改为
# Virtual hosts
Include conf/extra/httpd-vhosts.conf

保存退出。
2)配置文件,打开\conf\extra\httpd-vhosts.conf(apache2为/etc/apache2/apache2.conf)
在最后加上

<VirtualHost *:80>
    ServerAdmin xxx@qq.com
    DocumentRoot "/var/www"
    ServerName www.111.com
    ServerAlias www.111.example.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog  ${APACHE_LOG_DIR}/error.log common
</VirtualHost>


<VirtualHost *:80>
    ServerAdmin xxx@qq.com
    DocumentRoot "/var/www/soft"
    ServerName www.srcfile.cn
    ServerAlias srcfile.cn
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog  ${APACHE_LOG_DIR}/error.log common
</VirtualHost>

保存退出
3)重启apache

如何离线发现Android APP异常

2016年7月3日 由 Creater 没有评论 »

最近项目开发了一款android app,每次手动运行没有问题,但是让其自启动则奔溃,为了捕获异常,可以使用如下的方法来改进。
下来了解两个类:android.app.Application和java.lang.Thread.UncaughtExceptionHandler。

Application:用来管理应用程序的全局状态。在应用程序启动时Application会首先创建,然后才会根据情况(Intent)来启动相应的Activity和Service。本示例中将在自定义加强版的Application中注册未捕获异常处理器。

Thread.UncaughtExceptionHandler:线程未捕获异常处理器,用来处理未捕获异常。如果程序出现了未捕获异常,默认会弹出系统中强制关闭对话框。我们需要实现此接口,并注册为程序中默认未捕获异常处理。这样当未捕获异常发生时,就可以做一些个性化的异常处理操作。
大家刚才在项目的结构图中看到的CrashHandler.java实现了Thread.UncaughtExceptionHandler,使我们用来处理未捕获异常的主要成员,代码如下:

package net.unix8.crash;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

/**
 * UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.
 * 
 * @author user
 * 
 */
public class CrashHandler implements UncaughtExceptionHandler {
	
	public static final String TAG = "CrashHandler";
	
	//系统默认的UncaughtException处理类 
	private Thread.UncaughtExceptionHandler mDefaultHandler;
	//CrashHandler实例
	private static CrashHandler INSTANCE = new CrashHandler();
	//程序的Context对象
	private Context mContext;
	//用来存储设备信息和异常信息
	private Map<String, String> infos = new HashMap<String, String>();

	//用于格式化日期,作为日志文件名的一部分
	private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

	/** 保证只有一个CrashHandler实例 */
	private CrashHandler() {
	}

	/** 获取CrashHandler实例 ,单例模式 */
	public static CrashHandler getInstance() {
		return INSTANCE;
	}

	/**
	 * 初始化
	 * 
	 * @param context
	 */
	public void init(Context context) {
		mContext = context;
		//获取系统默认的UncaughtException处理器
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		//设置该CrashHandler为程序的默认处理器
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	/**
	 * 当UncaughtException发生时会转入该函数来处理
	 */
	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		if (!handleException(ex) && mDefaultHandler != null) {
			//如果用户没有处理则让系统默认的异常处理器来处理
			mDefaultHandler.uncaughtException(thread, ex);
		} else {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				Log.e(TAG, "error : ", e);
			}
			//退出程序
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(1);
		}
	}

	/**
	 * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
	 * 
	 * @param ex
	 * @return true:如果处理了该异常信息;否则返回false.
	 */
	private boolean handleException(Throwable ex) {
		if (ex == null) {
			return false;
		}
		//使用Toast来显示异常信息
		new Thread() {
			@Override
			public void run() {
				Looper.prepare();
				Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
				Looper.loop();
			}
		}.start();
		//收集设备参数信息 
		collectDeviceInfo(mContext);
		//保存日志文件 
		saveCrashInfo2File(ex);
		return true;
	}
	
	/**
	 * 收集设备参数信息
	 * @param ctx
	 */
	public void collectDeviceInfo(Context ctx) {
		try {
			PackageManager pm = ctx.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
			if (pi != null) {
				String versionName = pi.versionName == null ? "null" : pi.versionName;
				String versionCode = pi.versionCode + "";
				infos.put("versionName", versionName);
				infos.put("versionCode", versionCode);
			}
		} catch (NameNotFoundException e) {
			Log.e(TAG, "an error occured when collect package info", e);
		}
		Field[] fields = Build.class.getDeclaredFields();
		for (Field field : fields) {
			try {
				field.setAccessible(true);
				infos.put(field.getName(), field.get(null).toString());
				Log.d(TAG, field.getName() + " : " + field.get(null));
			} catch (Exception e) {
				Log.e(TAG, "an error occured when collect crash info", e);
			}
		}
	}

	/**
	 * 保存错误信息到文件中
	 * 
	 * @param ex
	 * @return	返回文件名称,便于将文件传送到服务器
	 */
	private String saveCrashInfo2File(Throwable ex) {
		
		StringBuffer sb = new StringBuffer();
		for (Map.Entry<String, String> entry : infos.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			sb.append(key + "=" + value + "\n");
		}
		
		Writer writer = new StringWriter();
		PrintWriter printWriter = new PrintWriter(writer);
		ex.printStackTrace(printWriter);
		Throwable cause = ex.getCause();
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		printWriter.close();
		String result = writer.toString();
		sb.append(result);
		try {
			long timestamp = System.currentTimeMillis();
			String time = formatter.format(new Date());
			String fileName = "crash-" + time + "-" + timestamp + ".log";
			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
				String path = "/sdcard/crash/";
				File dir = new File(path);
				if (!dir.exists()) {
					dir.mkdirs();
				}
				FileOutputStream fos = new FileOutputStream(path + fileName);
				fos.write(sb.toString().getBytes());
				fos.close();
			}
			return fileName;
		} catch (Exception e) {
			Log.e(TAG, "an error occured while writing file...", e);
		}
		return null;
	}
}

在收集异常信息时,朋友们也可以使用Properties,因为Properties有一个很便捷的方法properties.store(OutputStream out, String comments),用来将Properties实例中的键值对外输到输出流中,但是在使用的过程中发现生成的文件中异常信息打印在同一行,看起来极为费劲,所以换成Map来存放这些信息,然后生成文件时稍加了些操作。
完成这个CrashHandler后,我们需要在一个Application环境中让其运行,为此,我们继承android.app.Application,添加自己的代码,CrashApplication.java代码如下:

package net.unix8.crash;

import android.app.Application;

public class CrashApplication extends Application {
	@Override
	public void onCreate() {
		super.onCreate();
		CrashHandler crashHandler = CrashHandler.getInstance();
		crashHandler.init(getApplicationContext());
	}
}

最后,为了让我们的CrashApplication取代android.app.Application的地位,在我们的代码中生效,我们需要修改AndroidManifest.xml:

<application android:name=".CrashApplication" ...>  </application> 

因为我们上面的CrashHandler中,遇到异常后要保存设备参数和具体异常信息到SDCARD,所以我们需要在AndroidManifest.xml中加入读写SDCARD权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

这样异常信息就被保存到程序中指明的sdcard路径里了

IO币的《码农周刊》(第 113 期)

2016年7月2日 由 Creater 没有评论 »

程序设计

淘宝首页性能优化实践  小胡子哥的个人网站

本文从淘宝首页个性化引出的问题出发,从微观到宏观讲述了页面的优化实践。

拍照怎么搜题(上)  技术采拾

通俗易懂的解说

抓住六个点,谈唯品会的峰值系统应对实践  架构之美

闪购限时特卖业务特点决定了网站随时都需要处理高并发、大流量的用户请求

豆瓣混合开发实践  Android&iOS工程师之路

混合开发的直白的解释是 Native 和 Web 技术都要用

编程语言

Android 消息循环机制源码分析  学姐的技术成长之路

搞 Android 的不懂 Handler 消息循环机制,都不好意思说自己是 Android 工程师。

[译] 我眼中的 Android 架构  安卓黑科技

经验总结

Android Studio 2.0 正式版新特性  android开发小栈

尝鲜吧

Android 插件化原理解析  Android核心技术

插件加载机制

那些著名或非著名的 iOS 面试题:前编  iOS开发日常

系列文章

iOS 核心动画  iOS大牛之路

让开发更加酷炫

Swift 2.2 的新特性  SwiftCafe 快报

随着这次春季发布会,iOS 9.3,Swift 2.2 都已经发布。

Python 之生成器详解  fire烬的主题

从 Iterable, Iterator 知 Generator, Yield

Python 线程与协程  羽升笈

详细介绍

Python 模块受欢迎排行榜 Top 200  Python China

供参考

谁是最快的 Go Web 框架?  一亩三分地

供参考

[译] PHP 中的设计模式  王下 邀月熊的主题

本文主要讨论 Web 开发中的相关设计模式及其应用

[译] 深入理解 PHP 对象注入  PHP linux技术分享

代码详解

[译] 你好 ES2015  前端攻城狮

ES2015 是新版的 JavaScript

[译] 也许是你从未听过的在 CSS 领域最令人兴奋的发展  前端社区

发展趋势

[译] 看 Facebook 是如何优化 React Native 性能  工程师的星辰大海

Facebook 官方博文

【友盟+】猴年首场盛会:让我们聊聊 Alpha 狗、阿里 3 万亿、ROI、游戏出海的故事

工具资料

[译] Linux 系统调用权威指南  羽升笈

非常完整

一套完整的 Redis 入门 PPT  redis

实用

Linux 的进程优先级  Linux系统技术

细致讲解

Spark 在美团的实践  头条精选

经验分享

确保你网页的安全  SegmentFault 优质内容

深入解析

傅里叶分析之掐死教程完整版(2014)  白痴码农学做产品

生动讲解

ELK 在广告系统监控中的应用及 Elasticsearch 简介  有米科技研发团队

业界实战

[译] NPM 与 left-pad 事件:我们是不是早已忘记该如何好好地编程?  前端外刊评论君

值得思考

Freejam 通过用户友好型开发战略培养用户对 Robocraft* 的忠诚度 (英特尔开发人员专区)

开发人员所采用的方法离不开与玩家之间开放、透明的互动,如果没有各位玩家的反馈,他们根本无法改进这款游戏。

Node 读写 Excel 文件探究实践  NodeJs

主要阐述用 JS-XLSX、EXCEL-EXPORT 库来处理 Excel 文件

腾讯广州后台开发一面面经  牛客网精华贴

有点难

打造基于 GitHub 的 O2O 应用  Phodal

超炫的地图交互

Bash on Windows 抢鲜测试  微软技术相关

介绍及安装

Fetch 围观指南  Pikachu

XMLHttpRequest 的最新替代技术

连不通服务器服务怎么办  Yanmin

理论篇

程序员也需要了解期望值管理  Jim Liu的主题

你了解吗?

提升代码的可读性系列(一)  前端成长手册

基础篇

浏览器同源政策及其规避方法  PHP-前端

详细介绍

使用 Fragment 构建 Presenter(Android)  nekocode的主题

结合实例

用 Zabbix 和 Docker 搭建监控平台  杂说乱炖

Zabbix 是由 Alexei Vladishev 开发的一种网络监视、管理系统

ThoughtWorks 2016 年 4 月技术雷达发布  ThoughtWorks

技术参考

移动设备适配基础知识速成  淘宝开放平台精选

实用

Linux Shell Scripting Tutorial (LSST) v2.0  Awesome Qix

经典资料

可能是最接地气的 I/O 多路复用小结  周梦康的主题

言简意赅

用 Docker 做自动化持续集成  自动化测试

Macaca 部署完整版

创建和销毁对象的最佳实践  程序亦非猿的Android旅程

供参考

Native Page 与 Web View 之间的 JSBridge 实现方式  微软技术相关

为自己搭建一个鹊桥

基于内容和用户画像的个性化推荐  后端技术杂谈

基本介绍

Gradle 构建最佳实践  figotan的主题

结合具体应用场景

Sass (3.4.21) 中文文档  前端精要

一个 CSS 的扩展

大话程序猿眼里的高并发  大话程序猿眼里的WEB开发

个人观点

谈谈递归  Awesome Qix

通俗易懂

React + Redux todos 案例导读  K的全栈进击之路

实例

重新捡起你那吃灰的树莓派  关于python

试试吧

[译] 2016 年三大版式设计趋势  PHP-前端

供参考

webpack 入坑之旅  前端StepByStep

系列文章

运维知识体系 v0.6  运维精选

比较完整

[译] 15 个用于 GitHub 的 Chrome 插件  WEB资源网

收藏吧

深入浅出 Koa  NodeJs

主要针对 koa 的原理进行讨论

[译] 如何发布一个 Mac 应用并使其成为全球付费榜第一  _GET社区翻译计划

学习吧

如何设计实现一个 LRU Cache?  Awesome Coredump

结合代码

马尔科夫决策过程  algorithm&engineering

强化学习系列

解决使用 ShareSDK 第三方登录、分享遇到的坑  iOS大牛之路

经验之谈

Android 脸部识别官方 Demo  每日公开库@Juude-Song

留存备用

Surge 配置生成器  技术杂谈

快速生成属于你自己的 Surge 配置

React Native 实现的干货分享 App  react-native

很不错

tooltips:纯 CSS 打造的工具提示  JSdig

纯 CSS

一堆超赞的 JS 插件  web前端

收藏吧

idgo:兼容 Redis 协议的 ID 生成器  后端技术快报

Golang 实现

分享干货的《码农周刊》(第 114 期)

2016年7月2日 由 Creater 没有评论 »

程序设计

Hadoop NameNode 高可用 (High Availability) 实现解析  大数据那些事

从内部实现的角度对 NameNode 的高可用机制进行详细的分析

有赞 App IM SDK 组件架构设计  有赞技术精选

以 Android 客户端为例,记录有赞旗下 App 中使用自研 IM SDK 设计思路。

淘宝高可伸缩高性能架构的相关框架介绍  全栈工程师

简要介绍

编程语言

阿里巴巴、美团等各大互联网公司的 Java 类校招对本科生有什么要求?  猿blog

值得参考

关于 Android 进程保活,你所需要知道的一切  Android开发专题

本文不是教你做永生不死的进程

Objective-C Runtime 1 小时入门教程  iOS开发者.

适合入门

减小 ipa 体积之删除 frameWork 中无用 mach-O 文件  _iOS相关

新思路

这次 Swift 可能是真的要支持 Android 了  SwiftCafe

这项工作已经在进行了

[译] Python 导入模块的几种姿势  编程派

详细介绍

200 行 Python 代码实现简易版 2048  学算法的码农的主题

代码示例

使用 Go 构建命令行程序的快捷之道  golang神坛

介绍用于构建命令行程序的开源工具 mkideal/cli

在 Go 中使用面向对象 Web Servers  谢权blog

代码示例

[译] 展望 JavaScript 2016 年的趋势和生态发展  工程师的星辰大海

展望和梳理

JavaScript 被忽视的细节  小胡子哥的个人网站

《JavaScript 权威指南》笔记

[译] React Native 开源一年的总结  工程师的星辰大海

翻译自 Facebook 工程团队的官方博客

React Native 蛮荒开发生存指南  编码沉思录

踩坑和爬坑经验

工具资料

百度前端学院 2016 春季班任务  兔之技术笔记

收藏吧

[译] 面向程序员的数据挖掘指南  全栈工程师

一本用于学习基本数据挖掘知识的书籍

Mac 上自动配置好看易用的 Vim 环境  Barret李靖的主题

实用

Python 的练手项目有哪些值得推荐?  运维Linux&Python

收藏吧

一篇真正教会你开发移动端页面的文章(一)  HcySunYang前后左右端

详细介绍

前端打包工具 grunt 快速入门  NodeJs

大篇幅完整版

iOS 开发常用库  talisk斯温的技术博客

持续更新

Ansible 中文权威指南  Ansible

马哥 Linux 团队成员荣誉出品

面向英特尔 x86 平台的 Unity* 优化指南:第 1 部分 (英特尔开发人员专区)

展示 Unity* 软件中的多种工具和特性,以帮助您增强 Unity 项目的性能。

带你实现开发者头条(一):启动页实现  Android开发666

一步步教你

Facebook React Native 教程  全栈工程师

官方教程

第二届 Gopher China 大会幻灯片  程序员的朋友圈

干货

Vuex 源码阅读笔记  Lxxyx的主题

笔记中的 Vue 与 Vuex 版本为 1.0.21 和 0.6.2

优化高并发之协程  Edagarli’s Blog

简明介绍

深入理解信息安全领域相关术语  肥头的程序员之路

很完整

老司机使用 Redis 缓存复杂查询  阿毛的分享

经验分享

前端优化实践总结  Alexi的全栈之路

经验总结

我是怎么一个月将应用弄上 App Store 首页推荐的?  全栈

经验分享

一些酷炫的 Android loading 动画  211361的主题

收藏吧

自学 Sketch 整理  Node.js实战

作为全栈工程师,怎么可以不会点设计呢?

Sublime Text 特色插件推荐  Tong WANG的主题

持续更新

[译] 推荐 5 个值得学习 React Native 的开源项目  sugarball的前端分享

收藏吧

随谈 iOS 定制 UI 组件的过程  iOS开发随手记

详解

MySQL 5.7 对 JSON 的支持  杂说乱炖

实例介绍

妖怪和和尚过河问题  韩子迟的主题

一道有意思的编程思考题

webpack 实践最后一篇  前端Talk

系列文章

不带公式的机器学习算法整理  nicol_tao的主题

供参考

Spark 入门实例指南  初级程序猿的进化之路

适合新手

机器学习常见算法个人总结  小弧光黑板报

面试用

打造轻量级 ViewController 之抽离 DataSource/Delegate  iOS开发者.

结合代码

[译] 简约主义和字体排版  梦遥奇缘

最佳网页设计实践

推荐系统的典型推荐案例  nicol_tao的主题

通俗解释

[译] 将 Web 应用性能提高十倍的 10 条建议  Rover12421的主题

供参考

Awesome Python Books  不好奇的喵的主题

收藏吧

Learning Vue 1.0  杨进春的主题

Step By Step

跨域资源共享 CORS 详解  Lxxyx的主题

详细介绍 CORS 的内部机制

详细介绍 CORS 的内部机制  Android世界

通过代码更多了解 RN 的特性

使用 MVVM 架构实现的 iOS 头条 App  iOS干货分享

MVVM 架构的一次实践

LoginLib:对登录注册中发送验证码按钮和提交按钮的封装  安卓同学

使用方便

Cal-HeatMap:创建日历热点图的 JavaScript 模块  Awesomes-cn

用于可视化时间序列数据

React Native 最佳学习模版:F8 App 开源了  静逸秋水的主题

学习吧

Auto:Google 的 Java 代码生成器  每日公开库@Juude-Song

好东西

Web 前端助手  前端成长手册

浏览器插件

Voltron:Python 实现的黑客调试器前端  Python技术杂谈

可扩展

豆瓣 FM 第三方客户端 Murmur  ANDROID 可以这样开发哦

一个带白噪声效果的豆瓣电台第三方客户端

iBlog2:基于 Node.js 的个人开源博客系统  Node.js实战

响应式布局

WrapAPI: APIs for the whole web  _iOS相关

强大

鸟巢采集器:Web 版的网页数据采集工具  数据小白

功能强大

WeChatContacts:OC 实现的微信通讯录 UI  iOS干货分享

联系人按拼音首字母分组排序 A-Z,并且含联系人搜索功能。

KMNavigationBarTransition:无需代码统一管理导航栏转场(OC)  逐鹿 IT

同时支持竖屏和横屏

SimpleDeployer:基于 Git WebHook 的部署工具  技术杂谈

超简单