-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 18.4 KB
/
content.json
1
[{"title":"Android多线程下载","date":"2017-02-12T03:47:50.000Z","path":"2017/02/12/Android多线程下载/","text":"背景万事都有两面性,多线程下载也是,那么多线程下载的优点是什么呢?归根结底还是多线程的优点,这里我们暂且不去讨论它的利弊,只是讲解一下思想和实现方案。 实现分析我们用五个why的思想来分析一下这个问题: 怎么实现多线程下载?将下载逻辑在多个线程中同时运行。 怎么让每个线程下载对应的文件?将文件拆分成线程数对应的分数,进行分配。 怎么拆分文件?获取文件的长度,再按照线程数进行按比例分配。 怎么获取文件长度?利用HttpURLConnection的方法来获取内容长度 下载完成之后怎么办?各个线程都下载完成之后利用RandomAccessFile进行文件合并 好了,分析到这我们感觉已经可以实现了,我们再重新梳理一下逻辑,大概是,设定线程的数量,按照线程数量来分割要下载的文件,启动多个线程进行下载,最后合成一个文件。OK,撸起袖子就是干! 代码实现1、设置线程数,我这边是默认指定了三个,大家也可以通过服务器配置啊,或者某些算法来计算需要的线程数,根据实际情况来定。2、获取文件长度:12345678URL url = new URL(file.url);HttpURLConnection con = (HttpURLConnection)url.openConnection();con.setRequestMethod(\"GET\");con.setConnectTimeout(5000);if(con.getResponseCode() == HttpURLConnection.HTTP_OK) { int len = con.getContentLength(); //文件的总长度} 这样我们就获取到了文件的长度,然后就可以分割下载了,当然之前我们要初始化一些路径啊,RandomAccessFile什么的,大家可以下载源码查看。3、分割文件内容:123456789101112List<ThreadInfo> threadInfoList = new LinkedList<ThreadInfo>(); //建立线程信息列表 int block = mDownloadInfo.lenght/mThreadCount; //将下载文件分段 if(block > 0) { //start 根据线程数量分别建立线程信息 for(int i = 0;i < mThreadCount;i++) { ThreadInfo info = new ThreadInfo(i,mDownloadInfo.url,i*block,(i+1)*block-1,0); if(i == mThreadCount -1) { info.end = mDownloadInfo.lenght; //分段最后一个,结束位置到文件总长度末尾 } threadInfoList.add(info); //加入列表 } //end 根据线程数量分别建立线程信息 4、启动下载线程:12345678//start 启动下载线程for(ThreadInfo info : threadInfoList) { DownloadThread thread = new DownloadThread(info,mDownloadInfo,mTotalFinished); if(!mThreadPool.isShutdown()) { mThreadPool.execute(thread); }} 5、下载的逻辑和RandomAccessFile最后生成一个完整的文件:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960public void run() { URL url = null; HttpURLConnection con = null; //http链接 RandomAccessFile accessFile = null; //下载文件 InputStream inputStream = null; //输入流 try { int start = threadInfo.start+threadInfo.finished; //读取文件的位置 //start 初始化下载链接 url = new URL(threadInfo.url); con = (HttpURLConnection) url.openConnection(); con.setRequestMethod(\"GET\"); con.setConnectTimeout(5000); con.setRequestProperty(\"Range\", \"bytes=\" + start + \"-\" + threadInfo.end); //设置读取文件的位置,和结束位置 //end 初始化下载链接 //start 初始化下载到本地的文件 accessFile = new RandomAccessFile(new File(downloadInfo.filePath, downloadInfo.fileName),\"rwd\"); accessFile.seek(start); //设置开始写入的位置 //end 初始化下载到本地的文件 int responseCode = con.getResponseCode(); if((con.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) || (con.getResponseCode() == HttpURLConnection.HTTP_OK) ) { inputStream = con.getInputStream(); int finished = threadInfo.finished; //已经下载的长度 int readLen = -1; //读取的长度 byte[] buffer = new byte[1024*4]; long time = System.currentTimeMillis(); //start 读取输入流写入文件 while((readLen = inputStream.read(buffer))!=-1) { accessFile.write(buffer, 0, readLen); ); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { if(inputStream!=null){ inputStream.close(); } if(accessFile!=null) { accessFile.close(); } if(null!=con) { con.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } super.run();} 总结好了,主要下载逻辑就是这样,大家想看完整代码的可以点击下面的链接,希望大家可以喜欢,谢谢!源码下载","tags":[{"name":"多线程","slug":"多线程","permalink":"http://yoursite.com/tags/多线程/"}]},{"title":"利用Hexo和Github搭建自己的简单博客","date":"2017-02-07T13:27:24.000Z","path":"2017/02/07/利用Hexo和Github搭建自己的简单博客/","text":"申请Github账号这个大家可以自行申请,不会的也可以百度一下,这里也贴上一个百度经验的链接Github的账号申请方法 Github Pages的使用有了账号以后,首先点击新建仓库,如图: 然后到达仓库信息填写界面,如图:这里只要注意一个地方,就是仓库的名称,必须是:你的用户名.github.io因为我的已经申请了,没找到截图,所以这个是找的网上的鸿洋老师的截图,他的用户名是hongyangAndroid,所以他的用户名是hongyangAndroid.github.io。 安装Git客户端Git官方下载地址大家下载直接安装就行,一直下一步就可以,没什么特殊的,安装完成时候配置一下环境变量。搭建安装完成之后记得打开Git Base Here 配置用户名和邮箱,有些使用SSH我这边没有使用 git config --global user.name [username] git config --global user.email [email] 安装Node(必须)作用:用来生成静态页面的到Node.js官网下载相应平台的最新版本,一路安装即可。 正式安装HexoNode和Git都安装好后,首先创建一个文件夹,如blog,用户存放hexo的配置文件,然后进入blog里安装Hexo。 执行如下命令安装Hexo:npm install -g hexo 初始化然后,执行init命令初始化hexo,命令:hexo init 好啦,至此,全部安装工作已经完成!blog就是你的博客根目录,所有的操作都在里面进行。 生成静态页面hexo generate(hexo g也可以) 本地启动启动本地服务,进行文章预览调试,命令: hexo server 浏览器输入http://localhost:4000 我不知道你们能不能,反正我不能,一直打不开,不管他,我们直接配置到Github上。 Hexo和Github相结合在我们刚刚建立的blog的目录下面_config.yml的文件,打开之后,最下面配置Github deploy: type: git repo: https://github.com/OnlyTerminator/OnlyTerminator.github.io branch: master 然后执行命令: npm install hexo-deployer-git --save 最后啦,执行配置命令: hexo deploy 这一块可能要输入用户名和密码完成之后再浏览器中输入https://onlyterminator.github.io/就行了,我的github的账户叫onlyterminator,你们把这个改成你自己的github账户名就行了。 后期更新博客后期我们想要添加博客。只要在blog目录下面的source_posts下面添加.md文件就行,我们也可以通过命令来新建,位置也在source_posts下面 hexo new"postName" #新建文章 然后执行下面的命令部署到Github上: hexo clean hexo generate hexo deploy","tags":[{"name":"util","slug":"util","permalink":"http://yoursite.com/tags/util/"}]},{"title":"Android自定义Log库","date":"2017-02-06T12:51:03.000Z","path":"2017/02/06/Android自定义Log库/","text":"背景我们在开发的时候肯定会打一些Log,特别是在调试代码或者bug的时候,我们都会打一些Log日志来记录,但是当我们发布正式版本的时候,尼玛,要一行一行的去掉,这就尴尬了。 励志封装Log库本来想使用github上的Logger库的,但是感觉有点烦中,后面看到了鸿洋大师写过一篇关于Log库的文章 Android反观Log库后面我也是根据这个来简单的修改的 自定义内容 增加变量来区分debug模式还是release模式,在release的情况下将所有的Log日志都去掉。 利用StackTraceElement来输出我们的Log的位置,便于我们定位和寻找日志。 实现我们以i的log来作为例子:123456789101112/** * iiiiiiiiiiiiii * @param content */ public static void i(String content){ i(null,content); }public static void i(String tag,String content){ if (!sDebug) return; printer.i(getFinalTag(tag),content); } 其中的isDebug是我们的标识位,我们可以把它在初始化的时候来与编译类型绑定起来。其中Printer类是实现了打印Log日志功能的输出类:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152public class LogPrint implements Printer{@Overridepublic void d(String message, String str) { new DebugLogText(message).setup(str);}@Overridepublic void e(String message, String str) { new ErrorLogText(message).setup(str);}@Overridepublic void e(String message, String str,Throwable throwable) { new ErrorLogText(message).setup(str+throwable.getMessage());}@Overridepublic void w(String message, String str) { new WarnLogText(message).setup(str);}@Overridepublic void i(String message, String str) { new InfoLogText(message).setup(str);}@Overridepublic void v(String message, String str) { new VerboseLogText(message).setup(str);}@Overridepublic void wtf(String message, Object... args) {}@Overridepublic void json(String message, String json) { new InfoLogText(message).setup(json);}@Overridepublic void xml(String xml) {}@Overridepublic void clear() {}} 具体的输出类型是由对应的Log类型来产生,我们来看一个类InfoLogText:1234567891011121314151617181920212223public class InfoLogText extends LogText {public InfoLogText(String tag) { super(tag);}@Overrideprotected void setUpHeader() { Log.i(mTag, SINGLE_DIVIDER);}@Overrideprotected void setUpFooter() { Log.i(mTag, DOUBLE_DIVIDER);}@Overrideprotected void setUpContent(String content) { StackTraceElement targetStackTraceElement=getTargetStackTraceElement(); Log.i(mTag, \"(\" + targetStackTraceElement.getFileName() + \":\" + targetStackTraceElement.getLineNumber() + \")\"); Log.i(mTag, content);}} 总结我们可以看到,它实际调用的是系统的Log的日志方法,当然拼接了,对应的Log日志的类和行数,具体的原理我们可以查看上面提到的鸿洋的文章。好了,我么大家来看一下最后的日志效果 11-30 23:41:52.149 3580-3580/com.aotuman.weather I/aotuman: ******************************************** 11-30 23:41:52.149 3580-3580/com.aotuman.weather I/aotuman: (MainActivity.java:30) 11-30 23:41:52.149 3580-3580/com.aotuman.weather I/aotuman: is a test 11-30 23:41:52.149 3580-3580/com.aotuman.weather I/aotuman: ════════════════════════════════════════════ 最后附上源码的下载地址,喜欢的朋友可以下载使用,代码很少,也可以相互交流Android自定义Log库","tags":[{"name":"util","slug":"util","permalink":"http://yoursite.com/tags/util/"}]},{"title":"Markdown语法简单解析","date":"2017-02-06T10:05:51.000Z","path":"2017/02/06/markdown/","text":"Markdown?是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用。看到这里请不要被「标记」、「语言」所迷惑,Markdown 的语法十分简单。常用的标记符号也不超过十个,这种相对于更为复杂的HTML 标记语言来说,Markdown 可谓是十分轻量的,学习成本也不需要太多,且一旦熟悉这种语法规则,会有一劳永逸的效果。 使用 Markdown 的优点专注你的文字内容而不是排版样式。轻松的导出 HTML、PDF 和本身的 .md 文件。纯文本内容,兼容所有的文本编辑器与字处理软件。可读,直观。适合所有人的写作语言。 好了,我们直接步入正题吧,来讲解一下Markdown常用的集中语法: 1、标题标题是每篇文章都需要也是最常用的格式,在 Markdown 中,如果一段文字被定义为标题,只要在这段文字前加?#?号即可。 # 一级标题 ## 二级标题 ### 三级标题 以此类推,总共六级标题,建议在井号后加一个空格,这是最标准的 Markdown 语法。 2、列表我是一个程序员,所以在平时写一些文章的时候不太用到列表,但是它的语法也很简单,熟悉 HTML 的同学肯定知道有序列表与无序列表的区别。在 Markdown 下,列表的显示只需要在文字前加上?-?或?*?即可变为无序列表,有序列表则直接在文字前加?1.?2. 3. 符号要和文字之间加上一个字符的空格。 无序列表: * 入门详解 * 我是语法 入门详解 我是语法 有序列表: 1. 测试一下看看 2. 我是有序列表 测试一下看看 我是有序列表 3、引用如果你需要引用一小段别处的句子,那么就要用引用的格式。 >例如这样 例如这样 只需要在文本前加入?>?这种尖括号(大于号)即可 3、图片与链接插入链接与插入图片的语法很像,区别在一个?!号,插入链接的方法 [要显示的文字](实际的链接地址) [百度](http://baidu.com) 百度插入图片的实现方法![要显示的文字](实际的链接地址) ![百度的一张图片](http://upload-images.jianshu.io/upload_images/3004539-703d7cc6886ca745.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 4、粗体与斜体Markdown 的粗体和斜体也非常简单 用两个*包含一段文本就是粗体的语法, 用一个 * 包含一段文本就是斜体的语法。 下面看一个例子: **这里是粗体** 这里是粗体 ?*这里是斜体* 这里是斜体 5、表格表格是我觉得 Markdown 比较累人的地方,所以我很少用,实在是蛋疼,例子如下: | Tables | Are | Cool | | ------------- |:-------------:| -----:| | col 3 is | right-aligned | $1600 | | col 2 is | centered | $12 | | zebra stripes | are neat | $1 | 这种语法生成的表格如下: Tables Are Cool col 3 is right-aligned $1600 col 2 is centered $12 zebra stripes are neat $1 6、代码框对于我们这样的程序猿来说,这才是重点,如果你也跟我一样,是程序员,那你就可以用下面的方法来让自己的代码片段优雅的展示在文章里面,用一个`来包含你的代码片段 是键盘上那个 ~ 噢,不是’号,使用?tab?键即可缩进。我们看一个例子: `public void test(){ System.out.println("hello world!"); }` public void test(){ System.out.println("hello world!"); } 7、分割线分割线的语法只需要另起一行,连续输入三个星号?***即可。 老样子,我们还是来举一个栗子: 到这里,我们的语法讲解快结束了 *** 有问题大家一起交流啊! 到这里,我们的语法讲解快结束了 有问题大家一起交流啊! ##8、小结我也只是刚刚接触这种语法,想写一些东西记录一下,也给正在学习的朋友们做一下参考,大家有其他常用的语法可以给我留言,我会及时的补充到文章里面,谢谢大家!","tags":[{"name":"util","slug":"util","permalink":"http://yoursite.com/tags/util/"}]},{"title":"java反射的简单使用","date":"2017-02-06T10:05:50.000Z","path":"2017/02/06/java反射的简单使用/","text":"百度百科先来一些不太实用的解释:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 简单使用反射,在java中是非常常见和好用的一种方式,(但是大家需要知道,他的效率是比较低的,所以要慎用)当然在基于java语言而产生的Android中也是可以使用的,我们可以使用反射来获取一些系统并不开放,但是存在的类,从而调用他的一些方法,下面就简单的写一下,利用java反射来获取类和调用它的方法的实现。12345678910111213141516171819//需要被反射调用的类的路径 String className = \"com.example.test.JavaReflect\";Class reflect = null; try { //通过路径来获取java类 reflect = Class.forName(className); //实例化对应得类 Object javaReflect = reflect.newInstance(); if(null != javaReflect) { //反射出该Class类中的stringToUp()方法 stringToUp是方法名,String.class是参数类型 Method stringToUp = reflect.getDeclaredMethod(\"stringToUp\", String.class); //取消访问私有方法的合法性检查 stringToUp.setAccessible(true); //调用stringToUp()方法,第一个参数表示对应的类,第二个是方法的参数 String str = (String) stringToUp.invoke(javaReflect,\"java reflect test\"); System.out.println(\"result:\"+str); }}catch (Exception e) { e.printStackTrace();} 我们来看一下,在stringToUp里面做了什么: public String stringToUp(String str){ return str.toUpperCase(); } 其实就是一个对字符串转换成大写,然返回,好了我们来看一下输出结果 01-02 08:09:11.959 6150-6150/com.zxf.alpha I/System.out: result:JAVA REFLECT TEST 简直就是完美。 总结反射在Android中的应用范围也很多,比如我们项目有多个module的时候,你想在module里面调用主的程序的一个方法你就可以这么干,也可以用反射来调用一些系统为公开的方法,但是效率不太高。","tags":[{"name":"java","slug":"java","permalink":"http://yoursite.com/tags/java/"}]},{"title":"Hello World","date":"2017-01-06T10:05:50.000Z","path":"2017/01/06/hello-world/","text":"Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new \"My New Post\" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment","tags":[]}]