<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[持剑]]></title><description><![CDATA[深度,想法,执行力]]></description><link>https://blog.youkuaiyun.com/foolsheep</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; foolsheep]]></copyright><item><title><![CDATA[Java并发系列之volatile]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/80518141</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/80518141</guid><author>foolsheep</author><pubDate>Thu, 31 May 2018 00:11:49 +0800</pubDate><description><![CDATA[讲到Java并发，多线程编程，一定避免不了对关键字volatile的了解，那么如何来认识volatile，从哪些方面来了解它会比较合适呢？

个人认为，既然是多线程编程，那我们在平常的学习中，工作中，大部分都接触到的就是线程安全的概念。

而线程安全就会涉及到共享变量的概念，所以首先，我们得弄清楚共享变量是什么，且处理器和内存间的数据交互机制是如何导致共享变量变得不安全。



共享变量

能够在...]]></description><category></category></item><item><title><![CDATA[Java并发系列之Synchronized]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/80518130</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/80518130</guid><author>foolsheep</author><pubDate>Thu, 31 May 2018 00:09:30 +0800</pubDate><description><![CDATA[每一个刚接触多线程并发编程的同学，当被问到，如果多个线程同时访问一段代码，发生并发的时候，应该怎么处理？

我相信闪现在脑海中的第一个解决方案就是用synchronized，用锁，让这段代码同一时间只能被一个线程执行。 
我们也知道，synchronized关键字可以用在方法上，也可以用在代码块上，如果要使用synchronized，我们一般就会如下使用：



public synchroniz...]]></description><category></category></item><item><title><![CDATA[Android中使用Retrofit库进行Http通讯]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/50518907</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/50518907</guid><author>foolsheep</author><pubDate>Thu, 14 Jan 2016 17:00:11 +0800</pubDate><description><![CDATA[关于Retrofit2的使用流程]]></description><category></category></item><item><title><![CDATA[好记性不如烂笔头（三）]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/50464552</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/50464552</guid><author>foolsheep</author><pubDate>Tue, 05 Jan 2016 18:53:13 +0800</pubDate><description><![CDATA[SwiftHTTP发送Http请求刚学 iOS，利用SwiftHTTP来发送Http请求，就遇到一个坑，还是得记一下，以便以后回顾及查找：    func postWithSwiftHTTP() {
        let url = "http://ip:port/api"
        let params = ["param" : paramTextField.text!]]]></description><category></category></item><item><title><![CDATA[iOS开发学习笔记（零）]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/50461687</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/50461687</guid><author>foolsheep</author><pubDate>Tue, 05 Jan 2016 12:23:41 +0800</pubDate><description><![CDATA[创建firstapp项目，在Xcode上可见到以下的项目结构。项目结构
firstapp 
AppDelegate.swift
ViewController.swift
Main.storyboard
Assets.xcassets
LaunchScreen.storyboard
info.plist
Products 
firstapp.app
描述说明简单地描述一下各个文件的作用：
AppDel]]></description><category></category></item><item><title><![CDATA[Git Tag 的使用]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/50440021</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/50440021</guid><author>foolsheep</author><pubDate>Thu, 31 Dec 2015 10:27:21 +0800</pubDate><description><![CDATA[Git 提供了一个叫 tag的东西，即标签。作用每一次commit都会生成一串字符ID，如下所示：
  commit 7f2de2b2560e5d0623d64ef56f2128ed4ab532e0
这在正常的开发流程中没有什么问题，也不会去关心，但是等我们要发布的时候，或者已经发布了几个版本之后，要找回之前发布的版本到底是在哪个提交呢？记住这串id吗？ No way! 标签 (tag) 的作用就在]]></description><category></category></item><item><title><![CDATA[关于一个App的架构思考]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/50386142</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/50386142</guid><author>foolsheep</author><pubDate>Wed, 23 Dec 2015 12:34:39 +0800</pubDate><description><![CDATA[对于一个App来说，不管大小，我们在开发的过程中或多或少，都会碰到下面罗列的各种模块，需要我们去处理。
业务处理，对用户输入的校验和展现判断等
统计处理，对当前App或者对业务的数据统计等
UI效果，包括主题配置，按钮，输入框，动画效果，自定义控件等
更新升级，当前App的检查更新等
服务器通信，与服务器通信获取数据，心跳连接等
数据解析，比如对json，对xml等的解析等
分享处理，分享到微信朋友]]></description><category></category></item><item><title><![CDATA[RecycleView的基本使用方法]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/50381654</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/50381654</guid><author>foolsheep</author><pubDate>Tue, 22 Dec 2015 18:28:37 +0800</pubDate><description><![CDATA[为什么要使用RecycleView，而不再使用ListView记得每一次在用ListView的时候，在Adapter中，总是需要我们自己去创建一个ViewHolder，去存储ListItem的布局，这么做的原因在于findViewById()是一个很耗时间的操作，所以我们需要一个静态的对象将layout过的控件给保存起来，下一次刷新这个item的时候，就不再需要调用findViewById去View]]></description><category></category></item><item><title><![CDATA[好记性不如烂笔头(二)]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/44517163</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/44517163</guid><author>foolsheep</author><pubDate>Sat, 21 Mar 2015 17:19:27 +0800</pubDate><description><![CDATA[获取手机wifi信息   /**
     * 获取Wifi的Mac地址
     * @param context
     * @return
     */
    public static String getWifiBssid(Context context) {
        WifiManager wifi = (WifiManager) context.getSystemServ]]></description><category></category></item><item><title><![CDATA[对于Canvas和Bitmap的一点认识]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/44259473</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/44259473</guid><author>foolsheep</author><pubDate>Sat, 14 Mar 2015 14:47:11 +0800</pubDate><description><![CDATA[在Android关于Canvas的API描述中，一开始就如下描述：
  To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap),  
    a drawing primitive (e.]]></description><category></category></item><item><title><![CDATA[好记性不如烂笔头（一）]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/44257479</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/44257479</guid><author>foolsheep</author><pubDate>Sat, 14 Mar 2015 10:39:37 +0800</pubDate><description><![CDATA[获取系统设置状态 
我们可以通过Settings.System类来获取到一些系统设置的状态，所以我们可以通过以下代码来获取系统的状态，比如ACCELEROMETER_ROTATION 
等，不过有一点要注意的就是，Android的ROM太多了，不同的厂商可能会直接改掉Android的实现，然后自己实现一套，然后，就崩了。 
所以在真正处理的时候，我们需要去捕获异常，保证代码的健壮性。/**
* 获取]]></description><category></category></item><item><title><![CDATA[好记性不如烂笔头(零)]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/44038215</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/44038215</guid><author>foolsheep</author><pubDate>Tue, 03 Mar 2015 15:25:40 +0800</pubDate><description><![CDATA[俗话说，好记性不如烂笔头！ 
在平常的开发工作中，很多时候我们都会用到一些代码量比较小，但是却很有用的功能，但是，都只是写过就算，下一次再想起来用的时候，已经不知道该去哪儿找了。 
常常因为这些小点而浪费时间，也随着年纪渐长，智商有限，还是靠记下来，以备不时之需呀。获取圆形图片   /**
    * bitmap 要进行剪裁的位图
    * size 剪裁的圆形图片的大小
    */
   p]]></description><category></category></item><item><title><![CDATA[利用自定义View实现头像截取页面]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/43988045</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/43988045</guid><author>foolsheep</author><pubDate>Sat, 28 Feb 2015 18:28:50 +0800</pubDate><description><![CDATA[那么，如何制作这样一个效果呢，关键点在哪里呢？
做法其实可以有多种，
1）可以直接继承ImageView，然后在ImageView的OnDraw函数中直接绘制圆形或者方形的高亮圈；
2）也可以直接继承View，自己将Bitmap给传进来，在onDraw函数中先绘制图片，接着利用Path来绘制这个圆形或者方形的选择区域，利用Region.OP.DIFFERENCE来反向获取蒙板层。
不过利用clipPath来实现这个蒙板层的绘制，画出来的圆形会有锯齿，这个目前我还没有找到比较好的办法去掉这个锯齿，不知道有没有]]></description><category></category></item><item><title><![CDATA[Android学习小Demo（23）Aidl实现进程间通信]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/42835229</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/42835229</guid><author>foolsheep</author><pubDate>Sun, 18 Jan 2015 15:56:14 +0800</pubDate><description><![CDATA[我们知道，Android是靠Binder机制来实现进程间的通信，而上一篇文章中，我们利用AIDL，简单地从代码方面的角度讲解了在服务端中的Binder的存在形式，是以服务的实现存在的，而在客户端，则是以代理的形式，实现存在的只是一个关于服务端的Binder实现的引用。
理论上的东西我们要去学习掌握，但是也不能忽略了实际的动手能力，对吧。
今天，我们就一步一步地利用我们所了解地关于AIDL的知识，并且实现我们自己的小Demo。]]></description><category></category></item><item><title><![CDATA[跟面试官讲Binder（二）之关于AIDL的认识]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/42438813</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/42438813</guid><author>foolsheep</author><pubDate>Tue, 06 Jan 2015 00:14:27 +0800</pubDate><description><![CDATA[面试官开口说：“听你刚才所说，在Android系统中，都是利用Binder来进行进程间通信的，那我怎么听说，还有利用AIDL来实现进程间通信的呢？”。
其实，AIDL只是一种描述性语言，其全称是Android Interface Definition Language，即接口定义语言，利用ADT，我们可将自定义的AIDL文件转化成Java代码，而这些代码就能够来进行进程间通信（IPC）。为什么这些代码就能够进行IPC呢？那是因为，这些代码就是定义了Binder机制中作为服务端的Binder对象和客户端中用的]]></description><category></category></item><item><title><![CDATA[Android学习小Demo（22）带删除按钮的TextView]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/41594923</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/41594923</guid><author>foolsheep</author><pubDate>Sat, 29 Nov 2014 14:19:43 +0800</pubDate><description><![CDATA[我们创建了一个ClearableTextView，继承于TextView，关键的代码如下：
1）设置CompoundDrawables。
2）必须重载onTouchEvent方法。
这是因为在TextView中设置四边的图标时，并没有提供其对应的点击事件，所以这就需要我们自己去拦截用户的点击事件，判断用户的点击区。。。
3）定义一个接口，用来由外部实现，可在图标点击事件时触发处理，如下：
4）为了让文字不存在的时候，删除按钮不出现，我们可以自己定义一个setTextClearable方法，里面包装了Text]]></description><category></category></item><item><title><![CDATA[跟面试官讲Binder（一）]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/41518627</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/41518627</guid><author>foolsheep</author><pubDate>Wed, 26 Nov 2014 17:16:00 +0800</pubDate><description><![CDATA[1）Server启动了，他要创建一个Binder实体，它的句柄是0，比如BpBinder(0)，当设置了BINDER_SET_CONTEXT_MGR，驱动收到这个命令，它就知道是要将当前进程设置为ServiceManager，于是它就会当前这个Binder实体创建一个Binder节点（BinderNode），它在这里记录了 0 -> ServiceManager这样的mapping。
2）另一个Server启动了，它也会创建一个Binder实体，名字叫 XXXManagerService吧，但是它的句柄就不]]></description><category></category></item><item><title><![CDATA[关于ThreadLocal的一些认识]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/40892555</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/40892555</guid><author>foolsheep</author><pubDate>Fri, 07 Nov 2014 15:44:19 +0800</pubDate><description><![CDATA[可以看到，其是从current这个线程里去获取Values对象的，而如果不存在这个对象，其就会调用initializeValues方法，为线程的localValues创建一个新的Values对象。
最近再调用values的put方法，以当前ThreadLocal对象为key值，将我们的valule给存放到这个Values对象中，我们会马上意识到，Values实现的应该是一个类似Map的键值对的数据结构。
从这里，我们就可以意识到：
1）在每个线程中都存在一个Values对象。
2）无论我们在哪个线程中调用T]]></description><category></category></item><item><title><![CDATA[Android中利用Handler实现消息的分发机制（三）]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/40542793</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/40542793</guid><author>foolsheep</author><pubDate>Tue, 28 Oct 2014 17:55:31 +0800</pubDate><description><![CDATA[说到代码的可读性，有时候，我们更加看重代码之间的层次或者说模块化，耦合度等特点。
不同的业务逻辑，不同的功能，应该实现在不同的模块中，而模块与模块之间就可以通过一个消息来通信，而这种消息通讯方式，我们就可以利用Handler和HandlerThread来实现。
比如，最近做的一个浏览器的小Demo，其类图如下：
...
在不同的模块实现中， 我们可以调用registerHandler方法，将其对象的Handler注册到MessageDispatcher中，然后通过sendMessage方法，指定对应的目标，]]></description><category></category></item><item><title><![CDATA[Android中利用Handler实现消息的分发机制（二）]]></title><link>https://blog.youkuaiyun.com/foolsheep/article/details/40535631</link><guid>https://blog.youkuaiyun.com/foolsheep/article/details/40535631</guid><author>foolsheep</author><pubDate>Tue, 28 Oct 2014 11:31:34 +0800</pubDate><description><![CDATA[在这篇文章开始前，我们先总结一下前两篇文章中关于Handler， Looper和MessageQueue等的一些关键点：
0）在线程中创建Handler之前，必须先调用Looper.prepare(), 创建一个线程局部变量Looper，然后调用Looper.loop() 进入轮循。
1）当Handler创建之后，就可以调用Handler的sendMessageAtTime方法发送消息，而实际上是调用MessageQueue的enqueueMessage方法，将对应的消息放入消息队列。
2）每一个线程都只有]]></description><category></category></item></channel></rss>