<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/stephen8341</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; stephen8341]]></copyright><item><title><![CDATA[JMM内存可见性问题-工作内存读写主存时机]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/124201079</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/124201079</guid><author>stephen8341</author><pubDate>Fri, 15 Apr 2022 18:51:40 +0800</pubDate><description><![CDATA[工作内存和主存刷新时机是个很有意思的问题，网上有不少文章，但是写的都不是很全，所以这里亲自下场用代码实验


一、内存可见性：

内存可见性是并发编程中容易忽略的一个问题，但我认为他是一个非常重要的问题，只有对内存模型深刻理解才能发现这个问题。

主内存：线程共享内存，主要是堆和方法区；

工作内存：线程私有内存。相比于主存，工作内存离cpu更近性能更好，当线程访问公共变量时，会将变量copy一份到工作内存作为副本，后续都直接操作这个副本。

当然这里面核心的问题就是副本什么时候更新？什么时候重新从主存里.]]></description><category></category></item><item><title><![CDATA[Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.android.suppor]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/80393507</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/80393507</guid><author>stephen8341</author><pubDate>Mon, 21 May 2018 16:08:52 +0800</pubDate><description><![CDATA[“Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.android.support:appcompat-v7:26.+.”这个问题很蛋疼啊，本质上是v7包依赖问题。查了各种方法搞不定，最后试了重新添加依赖：这个是直接在库里面找的更具体的版本，果然，一替换就好了。。。坑爹的gra...]]></description><category></category></item><item><title><![CDATA[重磅整理---Android进程保活组件]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/71244626</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/71244626</guid><author>stephen8341</author><pubDate>Fri, 05 May 2017 21:54:27 +0800</pubDate><description><![CDATA[github地址： https://github.com/stephen8341/KeepProcLive

这里面集成的方案包括：

1.  Service指定为START_STICKY 被系统回收的进程会被系统重新拉起

2.  Service设置为前台进程 将后台进程设置为前台进程，提高进程优先级

   

3.  1像素Activity方案 关屏后加载1个像素的Act]]></description><category></category></item><item><title><![CDATA[android 硬件加速]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/56291424</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/56291424</guid><author>stephen8341</author><pubDate>Tue, 21 Feb 2017 20:47:44 +0800</pubDate><description><![CDATA[1. 硬件加速原理：
          将所有的cavas操作，比如drawBitmap drawLine 等转化为opengl的操作命令，存储到displaylist中，这样的好处是防止重复绘制？
        在对view做动画的时候，可以开启硬件加速，setLayerTyep   这样可以将view缓存到硬件纹理上，做动画的过程中就不会反复绘制view]]></description><category></category></item><item><title><![CDATA[android性能问题---项目实战]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/54669241</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/54669241</guid><author>stephen8341</author><pubDate>Sun, 22 Jan 2017 16:21:01 +0800</pubDate><description><![CDATA[1. HandlerThread导致oom
     背景：自动化测试过程中，每一个用例task里面会启动一个HandlerThread,但是HandlerThread是在task构造函数里面启动，而不是onStart里面启动，这样就导致初始化task集合时瞬间start了很多HandlerThread,并且如果中间退出测试，会导致没有开始的task里面的HandlerThread无法释放。最终]]></description><category></category></item><item><title><![CDATA[struct 的长度对齐]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/54577073</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/54577073</guid><author>stephen8341</author><pubDate>Mon, 16 Jan 2017 20:15:46 +0800</pubDate><description><![CDATA[结构体的sizeof的值并不是简单的将其中各个元素所占的字节相加，而是要考虑到存储空间的字节对齐问题

结构体默认的字节对齐准则：

1.           结构体变量的首地址能够被其最宽基本类型成员的大小所整除；

2.           结构体每个成员相对于结构体首地址的偏移量（offset）都是成员大小的整数倍，如有需要编译器会在成员之间加上填充字符；

3.      ]]></description><category></category></item><item><title><![CDATA[Sqlite线程安全]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/54019663</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/54019663</guid><author>stephen8341</author><pubDate>Wed, 04 Jan 2017 15:22:51 +0800</pubDate><description><![CDATA[sqlite是线程安全的，是指写线程安全，这里面是由SqliteConnection保证的，即一个database只有一个connection可以使用，所以天生是安全的。但是如果实在想支持多线程并发访问，可以使用enableAheadLogging开启一个写线程与多个读线程同时在一个SQLiteDatabase上起作用，它的机制是先写到临时日志文件中，再统一flush到数据库文件中。]]></description><category></category></item><item><title><![CDATA[关于两个设计模式的心得----模版方法模式、责任链模式]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/53385488</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/53385488</guid><author>stephen8341</author><pubDate>Fri, 09 Dec 2016 20:16:48 +0800</pubDate><description><![CDATA[最近在做一个蓝牙稳定性的自动化测试工具，就是用app模拟人的行为，自动去跑一些蓝牙相关的测试用例，譬如间隔传输数据、传输大数据、反复开关蓝牙等，再加上不同的参数配置，一共加起来大概有30多个case要跑，并且需要这些case串行执行，就是一个case跑完了才能执行下一个。这个时候如果没有一个设计框架在里面，直接硬编码实现每一个case会无比混乱，尤其是想实现串行执行会很麻烦。所以搞了一套框架，主要]]></description><category></category></item><item><title><![CDATA[http协议之我理解]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/52849892</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/52849892</guid><author>stephen8341</author><pubDate>Tue, 18 Oct 2016 16:30:31 +0800</pubDate><description><![CDATA[1.HTTP请求的请求行
  GET/POST


2.HTTP响应的状态行

  200 404 500


3.HTTP消息报头

  Connection:keep-alive   Cache-Control
 
 l         请求报头

 
    Accept：image/gif，表明客户端希望接受GIF图象格式的资源；Accept：text/ht]]></description><category></category></item><item><title><![CDATA[tcp协议之我理解]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/52849389</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/52849389</guid><author>stephen8341</author><pubDate>Tue, 18 Oct 2016 16:04:44 +0800</pubDate><description><![CDATA[1.有连接，可靠传输，数据按序到达的TCP


2. 为何建立连接是3次握手，而拆除连接是4次挥手。


   3次握手的目的很简单，就是分配资源，初始化序列号，这时还不涉及数据传输，3次就足够做到这个了，而4次挥手的目的是终止数据传输，并回收资源，此时两个端点两个方向的序列号已经没有了任何关系，必须等待两方向都没有数据传输时才能拆除虚链路，不像初始化时那么简单，发现SYN标志就初始化]]></description><category></category></item><item><title><![CDATA[view invalidate流程]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/52819270</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/52819270</guid><author>stephen8341</author><pubDate>Fri, 14 Oct 2016 21:59:28 +0800</pubDate><description><![CDATA[view.invalidate---viewparent.invalidateInparent---ViewRootImpl.invalidateInparent---ViewRootImpl.scheduleTraversals---Choreographer.postCallback
        (vsync信号到来)---performTraversals--performDraw--]]></description><category></category></item><item><title><![CDATA[canvas的save restore clipRect方法解析]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/52818292</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/52818292</guid><author>stephen8341</author><pubDate>Fri, 14 Oct 2016 19:10:40 +0800</pubDate><description><![CDATA[之前对canvas的这几个方法一直不是很清楚，今天花点时间总算搞明白了。
  1.save restore方法成对出现，用于保存恢复画布canvas,比如需要临时rotate canvas来画一些东西，画完之后再rotate回来画其它东西，这时就可以用这个兄弟
  2.cliprect方法，用于将画布切割到指定区域大小来作画，一般需要save restore方法保存恢复画布]]></description><category></category></item><item><title><![CDATA[watchdog杀死system_server导致系统重启问题分析流程]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/52642991</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/52642991</guid><author>stephen8341</author><pubDate>Fri, 23 Sep 2016 20:41:25 +0800</pubDate><description><![CDATA[下面是最近在解一个monkey测试过程中系统重启的bug的分析过程，从这里我们可以看一下对于watchdog杀死死锁进程的一般分析流程。（这里当是一个笔记，没有详细按着文章的逻辑来整理词汇和语句 汗汗汗）




1. watchdog: Blocked in handler on ActivityManager (ActivityManager)

      说明Activity]]></description><category></category></item><item><title><![CDATA[从mms源码看IM应用的架构<二>]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/51909332</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/51909332</guid><author>stephen8341</author><pubDate>Thu, 14 Jul 2016 17:35:21 +0800</pubDate><description><![CDATA[Action+ IntentService架构
  这一部分给大家总结一下mms里面对于后台任务的处理。正常情况下，一个互联网应用可能会涉及到n多的后台任务要运行，短信应用也不例外，不如插入短信到数据库，删除短信，标记为已读，发送短信，接收短信，下载彩信等。这些都是耗时任务，并且他们之间有些还有先后顺序要求，如果没有一个两个的后台任务管理框架，拿维护起来可就要了亲命了。
  这里我们就来看一下]]></description><category></category></item><item><title><![CDATA[从mms源码看IM应用的架构<一>]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/51906673</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/51906673</guid><author>stephen8341</author><pubDate>Thu, 14 Jul 2016 10:19:53 +0800</pubDate><description><![CDATA[最近因为项目在研究mms短信代码，本来以为现在短信已经是一个很鸡肋的功能了，没有什么价值了。但在看代码过程中，却在技术上收获不少，尤其是关于处理N多后台任务的架构设计很不错，可以学习google工程师的代码设计用到自己项目中。好了，下面会从几个方面分析：LoadManager框架、Action+IntentService框架、其它方面。
    
LoaderManager是什么？
正常情况]]></description><category></category></item><item><title><![CDATA[adb 查看wifi命令]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/51253855</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/51253855</guid><author>stephen8341</author><pubDate>Tue, 26 Apr 2016 20:40:03 +0800</pubDate><description><![CDATA[4. 打开WIFI指令
     svc wifi enable
5. 关闭WIFI指令
    svc wifi disable
ps|grep wifi 查看wpa_supplicant是不是已经起来了
6.查看ip:
   adb shell netcfg]]></description><category></category></item><item><title><![CDATA[快慢指针的时间复杂度探究]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/50608168</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/50608168</guid><author>stephen8341</author><pubDate>Fri, 29 Jan 2016 16:36:19 +0800</pubDate><description><![CDATA[对于“访问单向链表倒数第k个结点”，比较成熟的算法是快慢指针，即定义两个指针，一个指针先走k个结点，之后两个指针再一起走，从而拿到倒数第k个结点。

快慢指针算法如下：

LinkNode* findNode(LinkNode* head){//找到单向链表倒数第2个结点,快慢指针


LinkNode* temp = head->next->next;


LinkNode*]]></description><category></category></item><item><title><![CDATA[二叉查找树、平衡二叉树、红黑树]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/50508993</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/50508993</guid><author>stephen8341</author><pubDate>Wed, 13 Jan 2016 11:09:05 +0800</pubDate><description><![CDATA[先看几个基本概念：
   树：由根出发，指向n个孩子，孩子再指向孙子。。。这样一种数据结构
   二叉树：每个接点最多有两个孩子的树
   二叉查找树：每个结点的左子树
   平衡二叉树：每个结点左右子树的高度差不大于1
   红黑树：从任一节点到其每个叶子的所有简单路径 都包含相同数目的黑色节点。（当然还有其它性质）


几点关键点：
  1.平衡二叉树/红黑树都属于二叉查找树]]></description><category></category></item><item><title><![CDATA[Looper.myQueue().addIdleHandler，在activty界面显示后做一些事情,就在这个idlehandler中做]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/50498605</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/50498605</guid><author>stephen8341</author><pubDate>Mon, 11 Jan 2016 17:39:44 +0800</pubDate><description><![CDATA[相当于一个处理任务的时间节点。]]></description><category></category></item><item><title><![CDATA[FutureTask的cancel方法真的能停止掉一个正在执行的异步任务吗]]></title><link>https://blog.youkuaiyun.com/stephen8341/article/details/50433656</link><guid>https://blog.youkuaiyun.com/stephen8341/article/details/50433656</guid><author>stephen8341</author><pubDate>Wed, 30 Dec 2015 14:25:49 +0800</pubDate><description><![CDATA[public static void main(String[] args) {		ExecutorService executor = Executors.newSingleThreadExecutor();
		FutureTask futureTask = new FutureTask(new Callable() {
			@Override
			public String call()]]></description><category></category></item></channel></rss>