参考:
synchronized 的注意点:
reentrantlock 注意点:
try..finally { // 释放锁 }
参考:
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量。
因此被volatile
修饰的变量具备可见性,每一个线程对此变量的读取都保证是最新的
但是volatile
并不能保证原子性,所以如果做自增或读取再写等复合操作时,并不一定能得到预期的结果。
针对自增等情况,建议使用Atomic
想着的原子操作类来完成
而更复杂的操作则借助synchronized
、lock
来处理并发volatile
则适合单一操作的情况,如定义flag
用于逻辑判断
参考:
个人理解,Jvm 屏蔽了硬件使得程序可以跨平台运行,JMM(Java内存模型)则是对真实硬件内存架构的屏蔽。
在涉及多线程上,JMM 通过happen-before 规则来解决线程之间的通信和同步。
开发者参考这份指南,JMM 遵守这份规则,从而保证所写的正确同步的多线程程序执行的结果与预期一致
而编译器也能根据这份规则尽可能的优化程序的并发度,使得编译出来的程序更加高效的使用硬件资源
常见的规则有8个:程序顺序规则、监视器锁规则、volatile 变量规则、传递性、线程启动规则、线程中断规则、线程终结规则、对象终结规则
简单说下就是:
了解 JVM,帮助我们知悉程序的运行环境和运行情况
了解 JMM,帮助我们了解程序的内存管理情况如分配、回收
了解 hb 规则,帮助我们写出多线程安全且高效的程序
更详细的内容可以细读一下上面列的参考文章
参考:
在阅读上面的参考文章之前注意了
请务必认为文章中的单例对象一定有其他需要初始化的变量,否则 DCL 不存在失效之说。
请务必认为文章中的单例对象一定有其他需要初始化的变量,否则 DCL 不存在失效之说。
请务必认为文章中的单例对象一定有其他需要初始化的变量,否则 DCL 不存在失效之说。
因为失效的原因,简单点说就是由于指令重排线程A先做了变量的赋值但还未执行初始化,于是线程B拿到了一个未初始化好的单例对象,于是 GG 了…
下面是两种解决方法:
1. 将单例对象声明为volatile
从而禁止指令重排保证其他线程拿到的是一个初始化好的单例对象
2. 利用类加载并初始化在多线程时依旧只会被加载一次的特性(由 Jvm 保证),将单例作为静态变量并直接构造
关于第二种,如果没有懒加载的需求,甚至可以省去内部静态类
参考:
参考:
标记清除算法
首先遍历标记出所有存活的对象,标记完成后清除未标记的对象。此算法缺点在于效率低下并且会产生内存碎片。
复制算法
将内存分成两份,每次 GC 时将存活的对象复制至另一份内存中,复制完后清理内存。典型的空间换时间,缺点是浪费内存空间,优点则是简单高效,并且不需要考虑内存碎片问题
标记压缩算法
对标记清除算法的改进,在标记完后将存活对象移至一端再作清除来避免内存碎片问题。
分代算法
将内存分为新生代和老年代。新生代中经历几次 GC 后依旧存活的对象将被移至老年代。
新生代存活率低,采用简单高效的复制算法
老年代存活率高,采用标记压缩算法来避免额外空间的分配担保
Serial / Serial Old 收集器
串行收集器,GC 过程会暂停其他所有工作线程。简单高效,单线程中效率最高
ParNew 收集器
新生代 GC 策略。采用复制算法并行工作。Serial 的多线程版
Parallel Scavenge / Parallel Old
“吞吐量优先”收集器,并行工作,具有自适应调节策略。其目标是达到一个可控制的吞吐量。
CMS 收集器
全称Concurrent Mark Sweep。目标是获取最短回收停顿时间。
过程大致为初始标记 -> 并发标记 -> 重新标记 -> 并发清除
优点是:并发收集、低停顿
缺点是:
对CPU资源非常敏感。当 CPU 较少时,并发收集过程中对应用程序的影响较大
无法处理浮动垃圾。由于是并发收集,收集过程中程序依旧在产生垃圾,而这些浮动垃圾只能等下次 GC 时进行回收
采用是标记清除算法,会产生大量内存碎片。在无法分配连续的大空间时只能触发 Full GC 解决
G1收集器
将整个Java堆划分为多个大小相等的独立区域(Region)。从整体上看采用“标记整理”算法,从局部(两个Region之间)上来看是基于“复制”算法,因此不会产生内存碎片
过程大致为初始标记 -> 并发标记 -> 最终标记 -> 筛选回收
类加载主要有以下过程:
Java 中类加载采用的是双亲委托机制。加载时均一层层交由父类去加载,只有当父类明确无法加载时,才由当前类加载器加载。
类加载器:
上图结合文章 Java字节码结构解析 会更好理解。
类的加载阶段就是根据上图的定义将 class 二进制文件解析成 class 对象。
ThreadLocal 的 get / set 方法实际上都是对当前线程内的 threadLocals 变量进行读取或赋值
每个线程的 threadLocals 都是私有变量,对其他线程不可见。
虽然每一次都是通过同一个 threadLocal 进行操作,但是实际上都转变为对当前线程内的 threadLocals 变量进行操作
操作时 threadLocal 也只作为 key 使用以及用于读取默认值,例如 sLocal.set(10)
则是以 sLocal
作为 key,将 10 存入当前线程的 threadLocals 中
适用场景:每个线程需要有自己单独的实例,实例需要在多个方法中共享,但不希望被多线程共享
例如 Android 中的 Looper.myLooper()
就是使用 ThreadLocal 实现,从而保证每一个线程调用 myLooper()
时拿到的都是属于自己的 looper 对象
参考:
CAS 全称是 Compare And Set。这是一个由处理器提供支持的操作,并且是原子性操作不可中断。其原子性则由处理器通过总线锁或者缓存锁定来保证
CAS 操作包含一个内存地址V、一个期望值A和一个新值B,只有当内存地址V中的值与期望值A相等,才会将内存地址V的值更新为新值B。整个过程不可中断
我们常用的 Atomic 包中的类以及非阻塞的线程安全队列其实现原理就是 CAS
拿 AtomicInteger 举个例子,当前线程A 与线程 B 同时进行自增操作
线程A 首先从主内在V中取得值为0,保存至线程本地内在副本变量A1中,此时。。。线程A睡觉去了zzzz
线程B 运行,也从主内存V中取得值为0,保存至线程本地内存副本变量A2,接着A2+1,得到新值 B2 为 1。然后划重点了,线程B 进行 CAS 操作,比较 V 和 A2的值,都为 0,于是将 B2 更新至主内存 V中。
自增完成,此时主内存V的值为 1
线程A睡醒,接着睡前的操作对A1+1,得到新值B1 为 1,线程A也同样进行CAS操作,比较 V 和 A1 的值,1 != 0,于是B1不进行赋值操作,CAS 操作返回 false。线程A只好从头开始,取值,运算,CAS 操作,直到成功
通过以上流程,AtomicInteger 实现线程安全的自增操作。语言层没有涉及到同步操作,而是由硬件提供的CAS 操作来完成。
基于 CAS 的线程安全机制相比 synchronized 方式更高效,但存在以下问题:
怎么办?难道先去睡一觉?
其实解决办法是有有两个。
打开目录 ~/.gradle/wrapper/dists
查看当前已经下载了什么版本的 gradle
修改项目的 gradle/wrapper/gradle-wrapper.properties
文件
重新打开 Android Studio 或者重新运行 assemble 即可。
如果是完全全新的环境,并没有已经下载好的 gradle 版本或者必须使用指定版本的 gradle 的话
那我们直接使用迅雷等下载工具下载,这样会快好多。
下载完成后,将 zip 文件移至 gradle 指定版本目录下即可。
这里说明一下,以上只适用于 Linux 平台和 Mac 平台。
Windows放哪?赶紧换系统吧(自行解决,Windows 也有类似的目录)。
再有一点,中间的55gk2rcmfc6p2dg9u9ohc3hw9
每个人的都是不一样的,这是随机生成的。
接下来我们重新执行 assemble 命令,就会发现,直接跳过了原来的 Download 阶段,直接对我们刚才下载的 gradle-3-3.zip 文件进行了解压。
快速无法解决下载 Gradle 问题
以上就是本文的全部内容。如果还有其他更好的方法,欢迎告知。
]]>
|
|
|
|
|
|
使用方法
awk甚至可以使用条件判断,循环,变量等完成工作.更详情的内容可自行搜索
在使用crontab之前,首先要保证本机的时间正确.最简单的办法是直接与网络时间服务器同步一下即可.
常用服务器如下:
|
|
如果没有网络,则可以通过date
命令自己手动调整时间
|
|
例如希望将磁盘大小修改为100G
调整好磁盘大小好,还需要进入系统调整分区大小,否则新增加的空间依旧无法使用
Windows 可以采用自带的分区工具,
Linux 系列则可以使用 GParted 工具进行分区,如果是非图形界面,则考虑采用 Linux 安装盘进入图形界面进行分区。当然如果比较厉害,那么请使用 fdisk 及 resize2fs 进行分区 =。=
每一次发布版本或者提交功能前,使用monkey经常可以跑出一些潜在的问题,非常有用.
结合前面提到的awk命令,组合一下可以写成一个脚本用于每次结束monkey时调用
多次打开APP,并退出后,调用以下命令,查看结果.
如果Views
和Activities
的结果不为0,则说明存在内存泄漏情况.
需要结合Android Device Monitor
或LeakCanary
进行排查
在进行 NDK 开发的时候,当对std::string 变量进行Copy Value
操作或者在 lldb
中进行 po
操作时
会发现,当字符串长度超过 300 个字符时,复制出来的字符串最后几位是...
出现这个问题其实是lldb
的限制 300 个字符输出的限制,把这个重新设置一下就好。
在 Native Debug 状态下进行断点,然后切换到lldb 标签页,输入以下命令
然后运行至需要查看变量的代码行,这时候再Copy Value
或者在lldb
中进行po
操作
拿到的字符串就是完整的了。
ctrl+f12
此快捷键可以调出当前文件的大纲,并通过模糊匹配快速跳转至指定的方法。
勾选上“show anonymous classes”后其功能相当于Eclipse中的ctrl+o
ctrl+alt+h
查看某个方法的调用路径。
ctrl+shift+i
不离开当前文件当前类的情况下快速查看某个方法或者类的实现。通过大概预览下调用的方法,可以避免许多未知的坑。
如其名,书签。帮助快速回到指定的位置,实际使用中简直爽得不行。
f11
将当前位置添加到书签中或者从书签中移除。
shift+f11
显示有哪些书签。
ctrl+shift+a
对于没有设置快捷键或者忘记快捷键的菜单或者动作(Action),可能通过输入其名字快速调用。神技!!!
例如想要编译,只需要输入”release”,则列表框中就会出现”assembleRelease”选项,选择就可以进行编译。
alt+shift+up/down
上下移动行,这个没什么好说的,肯定会用到。
ctrl+y,ctrl+x, ctrl+d
删除行,删除并复制行,复制行并粘贴,必备。
Alt+(1左边的那个键)
此快捷键会显示一个版本管理常用的一个命令,可以通过命令前面的数字或者模糊匹配来快速选择命令。
极大的提高了工作效率,快速提交代码、暂存代码、切分支等操作操作如鱼得水。
ctrl+shift+f12
关闭或者恢复其他窗口。在编写代码的时候非常方便的全屏编辑框,可以更加专心的coding…
ctrl+p
在调用一些方法的时候免不了会忘记或者不知道此方法需要哪些参数。> **ctrl+p`可以显示出此方法需要的参数。必备技能之一。
shift+f6
重命名变量或者方法名。重构神技。
通过右键断点,可以对一个断点加入条件。只有当满足条件时,才会进入到断点中。调试神技,只对自己关心的情况进行调试,不浪费时间。
点击Attach Debugger
(即绿色小虫旁边那个)可以快速进入调试而不需要重新部署和启动app。
可以选择为此功能设置一个快捷键或者通过前面提到的Find Actions(ctrl+shift+a)
输入”attach”进行调用。
按住Alt
点击想要查看的变量或者语句。如果想查看更多,则可以按Alt+f8
调出Evaluate Expression
窗口来自行输入自定义的语句。
Find Actions(ctrl+shift+a)
输入”analyze stacktrace”即可查看堆栈信息。
Find Actions(ctrl+shift+a)
输入”Analyze Data Flow to Here”,可以查看某个变量某个参数其值是如何一路赋值过来的。
对于分析代码非常有用。
强大的神技之一,用过vim的vim-multiple-cursors或者Sublime Text的多行编辑都不会忘记那种快感!
也许不是平时用得最多的技能,但是却是关键时刻提高效率的工具。
快捷键:Alt+J
在vim中叫作块编辑,同样神技!使用方法:按住Alt
加鼠标左键拉框即可
PS:发现Ubuntu下不可用,代替方法为按Alt+Shift+Insert
之后拖框选择。
但是经过这么操作之后,神技就大打折扣了。估计是与Ubuntu的快捷键冲突了。
看图!
AlarmManager
我们可以设置一些闹钟。在一些指定的时间点启动我们的服务进行处理事件。AlarmManager
时,注意以下几个点将会帮助你更好的使用这个特性。
如果设置闹钟所触发的任务中包含网络请求时,建议为这个触发时间点增加随机性。
假设设定在早上8点发起查询天气预报的网络请求,不增加随机性。那么在8点这一时刻,服务器将会收到大量的请求,造成服务器压力过大,如果设备足够多,服务器甚至会无法正常提供服务。
因此,增加随机性,将这些请求分散到不同的触发时间点,例如部分用户触发时间为7点,而部分用户触发时间为8点。可以根据需要,分散到更多更随机的时间区间。
这样做可以有效的错开这些网络请求的时间,减缓服务器的压力,从而服务器可以提供更好更快的服务。
当使用setInexactRepeating()时,系统可以在同一时间触发多个应用的闹钟,从而有效的减少设备的唤醒次数。
而从Android4.4开始,所以的闹钟触发时间点都不再是准确无误的。
因此,为了降低耗电量,在不是非常需要准确时间触发的情况下,建议使用setInexactRepeating()
。
ELAPSED_REALTIME
是基于系统启动到现在的时间,因此ELAPSED_REALTIME
适合用于设置需要在未来多长时间之后触发的闹钟。
例如希望在半个小时之后触发等。
|
|
RTC是基于当前时区的确切时间,因此适合用于设置需要精确到某一天的某个时刻进行触发的闹钟。
例如希望在下午2点钟的时候触发:
|
|
wakeup版本为:
非wakeup版本:
他们的区别在于设备屏幕熄灭状态下的反应。wakeup版本触发时,当屏幕处于熄灭状态时依旧会唤醒设备,从而可以执行所必要的操作。而非wakeup版本触发时,如果此时屏幕处于熄灭状态,则不会把设备唤醒,而是等到用户或者是其他操作把设备唤醒时,才会把pendingIntent传递过去从而执行任务。
]]>当有需求需要屏幕常亮时(例如游戏或者电影),最好的方式是在Activity中使用FLAG_KEEP_SCREEN_ON
。但是这个标志不要在service或者其他组件中使用,仅能够在Activity中使用。
|
|
这种方式相对于wake locks
(后面会讲到)的优势在于,一是不需要申请权限即可使用;二是不需要考虑资源的释放,如wakeLock。
除此之外,还可以在xml布局中指定这个flag,具体方法是使用android:keepScreenOn
属性。
在xml指定android:keepScreenOn
属性与在Activity中addFlag效果是一样的,只是方式不同,可根据需要来进行选择。
而当不再需要保持屏幕常亮时,只要调用clearFlags()
方法清除掉FLAG_KEEP_SCREEN_ON
即可
在执行某些重要的操作时,确实需要在屏幕熄灭后,cpu依旧能保持运行状态来完成这些操作。
这时可能通过申请WAKE_LOCK
来保持cpu处于运行状态。但是记住不要长时间地hold住,在完成操作后一定要释放掉,否则耗电会非常严重。
申请wake lock,首先需要在manifest文件中添加申请权限:
然后在需要保持cpu运行状态操作的地方法,申请wakelock:
以上便能保证当手机屏幕熄灭后,cpu依旧能保持运行状态,来完成那个比较重要的操作。
需要注意的是,在完成这些操作之后,一定要记得释放掉wakeLock。长时间保持cpu运行状态将会使手机的电量快速的耗尽。到时,app将会出现在耗电量排行榜的首位。
如果需求hold住wakeLock的service是通过BroadcastReceiver来启动的,那么更加建议使用WakefulBroadcastReceiver,而不是直接调用wakeLock.acquire()
。
因为WakefulBroadcastReceiver能很好的帮我们管理hold住的wakeLock。
使用WakefulBroadcastReceiver与使用普通的BroadcastReceiver并没有多大的区别,不同的是在于启动service之后,需要调用startWakefulService
来保持cpu运行状态。
而当service中处理完任务之后,只需要调用completeWakefulIntent
方法即可完成释放
使用WakefulBroadcastReceiver是官方比较推荐的方式,原因从startWakefulService
和completeWakefulIntent
可以看出,不需要写多余的getSystemService等方法去进行wakeLock,WakefulBroadcastReceiver已经替我们封装好了。并且这两个方法中使用了synchronized关键字,是线程安全的。WakefulBroadcastReceiver还会负责管理这些申请过来的wakeLock。
|
|
通过判断savedInstanceState是否为null来得知Activity是否已经创建过
如果是,则没必要再重新添加Fragment,否则会导致Fragment重叠。
|
|
通过setArguments方法,可以把Activity接收到的Intent中的参数传递给Fragment
而在Fragment的onCreateView方法中,可以通过getArguments()的方式来获取传递过来的参数,然后对View进行初始化。
而官方推荐使用setArguments方式进行传递参数,而不推荐new HeadlinesFragment(“参数”);构造函数的方式传递,原因在于当系统需要重建Fragment时,setArguments方式所传递的参数仍然存在。具体分析可查看此文:http://blog.csdn.net/tu_bingbing/article/details/24143249
|
|
在进行替换Fragment操作时,如果同时通过addToBackStack把此事务添加到后退栈中
当用户按返回键时,则可以回退到前一个Fragment。
原因在于FragmentActivity的onBackPressed函数中会先判断后退栈中是否为空,如果不为空,则回滚当前事务,即返回到前一个Fragment;否则如果为空,则结束此Activity
除此之外,如果使用了addToBackStack,则前一个Fragment并不会被销毁(destroyed),而只是停止状态(stopped)
每一个Fragment都是一个独立的可重用的UI组件,不应当与其他外部的组件产生强耦合。
因此,Fragment与Activity的交互同一些控件类似,都是采用提供接口的方式进行实现。而Activity则可直接调用Fragment的公有方法。
而Activity则采用直接调用Fragment公有方法的方式与Fragment进行交互
Android官方文档
Android 源码设计模式解析与实战
Android群英传
head First 设计模式
大话设计模式
设计模式之禅
架构之美
黑客与画家
软件随想录
编程之美
程序员修炼之道
软件开发者路线图—从学徒到高手
带人的技术
拿工薪,三十几岁你也能赚到600万
买基金为自己加薪
设计心理学2:如何管理复杂
为保证能一次性成功,后续不折腾,最后先把之前的Emacs版本相关的信息清除。
|
|
从Ubuntu的源中我们只能得到Emacs23,而官方Emacs则只能够自己编译。编译过程需要进行很多配置和安装一些库。
因此采用PPA源的方式进行安装,安装别人编译好的版本。
|
|
如果比较喜欢新特性,希望经常更新,则可以添加以下snapshot的PPA源
|
|
执行以下命令安装Emacs24
如果是要安装snapshot版本,则执行以下命令
在Android中,常用的Java与Js交互的实现方式是通过函数addJavascriptInterface进行添加在Js中使用的回调代理类。
这种方法虽然方便,但是写出来的js代码并不通用。如果IOS也要实现类似的功能或业务,则IOS要另外写一套Js代码。所以不太推荐。
推荐使用重载URL的方式来实现,因为基本所有的平台都拥有在加载某个URL之前进行一些处理的回调函数。所以这种方式会更加的通用。
在Android的WebView控件中,默认对JS的alert函数是没有任何反应的
要想弹出对应的对话框,则需要我们自己进行实现
具体实现代码如下:
通过以上代码就可以实现当JS中执行alert时,在Android上以原生的对话框显示出来,当然这里也可以直接Toast。
而这段代码中需要注意的地方有两点:
返回值必须为true
。
返回true,则说明已经处理了,不需要交由WebChromeClient来执行。而如果返回的是false,则Webview会继续执行后续的js代码,现象就是,弹出对话框之后,用户还没点确定,后续的js代码已经执行完了.
最后必须调用result.confirm()。
原因在于,如果没有调用此函数,则后续的JS代码将无法继续执行下去。最常见的现象就是,alert对话框只出现一次,第二次再进行alert的时候没有任何反应。其实这里是因为没有调用confirm函数,就相当于在浏览器中alert之后,用户没有点确定。
result.confirm()应该放到onClick回调中。
正如前面说的,调用confirm函数,就相当于用户点击了确定按钮。因此,我们要把confirm函数的调用放到Android原生对话框的“确定”按钮的回调函数中进行调用。
之前没理解透,把confirm函数放在了builder.show之后进行调用,结果现象是alert之后,对话框弹出来了,但是后续的js代码没有阻塞,而是继续执行下去了,变得就像是异步了一样,和在chrome中调用js代码的执行逻辑不一致。
不过,如果需求就是要直接执行下去,那也可以,只要理解了就行。
对于有证书问题的网页,比如过期、信息不正确、发行机关不被信任等,Webview默认情况下会拒绝访问。而PC端浏览器的处理则是提供用户进行选择是否要继续,在android也是可以实现的。
首先第一种是直接继续,不需要让用户进行选择
这里要注意的是,千万不要调用super的onReceivedSslError方法,因为此方法中已经调用了handler.cancel()。
如果调用了,则会出现第一次无法加载,第二次却能正常访问的现象。
当设置了WebviewClient时,在shouldoverrideurlloading中如果不需要对url进行拦截做处理,而是简单的继续加载此网址。
则建议采用返回false的方式而不是loadUrl的方式进行加载网址。
为什么这么建议呢?
因为如果采用loadUrl的方式进行加载,那么对于加载有跳转的网址时,进行webview.goBack就会特别麻烦。
例如加载链接如下:
A->(B->C->D)->E 括号内为跳转
如果采用return false的方式,那么在goBack的时候,可以从第二步直接回到A网页。从E回到A只需要执行两次goBack
而如果采用的是loadUrl,则没办法直接从第二步回到A网页。因为loadUrl把第二步的每个跳转都认为是一个新的网页加载,因此从E回到A需要执行四次goBack
只有当不需要加载网址而是拦截做其他处理,如拦截tel:xxx等特殊url做拨号处理的时候,才应该返回true。
在使用RotateAnimation发现了这个问题。相信有很多人在使用RotateAnimation做旋转动画的时候都有过这样的问题,
就是动画旋转一周后,会有一段比较明显的停顿。于是,很多人没有深究其原因,通过将旋转角度设置为355而不是360这样的小技巧来弥补这个停顿时间,从而缓解了停顿感。
其实深究下来,这都是Interpolator的错。
仔细看,我们可以发现,动画的旋转过程其实是先加速,而后减速的。
所以由于开始的时候比较慢,结束的时候也比较慢,也就造成了动画在旋转快一周的时候有明显的停顿(其实只是动画变慢了而已)
但是setInterpolator函数却告诉我们,动画默认的interpolation是线性的,也就是说不存在先加速再减速的问题。
以下是setInterpolator的函数说明:
虽然函数说明是说默认的Interpolator是linear interpolation,但是我只能说,别被骗了,以事实说话吧。
通过在Animation类中搜索mInterpolator,可以发现只有一个地方对mInterpolator进行赋值了。
那个函数就是ensureInterpolator。
从函数的实现中可以看到,当用户没有调用setInterpolator函数对mInterpolator进行初始化的时候,
ensureInterpolator会给mInterpolator赋值一个AccelerateDecelerateInterpolator
而这个,正是先加速,而后减速。也就是造成动画完成一个周期后产生停顿的原因。
所以,我们在使用RotateAnimation的时候,要想解决动画停顿的现象,只需要把Interpolator设置成线性的就可以了。
因此,折腾了一个午休时间,终于在landscape+主题里加入了文章目录模块。以下是瞎折腾的步骤。
打开 \landscape-plus\layout_partial 目录下的 article.ejs 文件
找到相应的位置,加入以下文章目录那一块的代码
打开 landscape-plus\source\css_partial 目录下的 article.styl 文件
在最后加入以下样式
|
|
打开 landscape-plus\source\css 目录下的 _variables.styl文件
任意一个位置添加以下颜色变量
通过以上三步,即可在每一篇文章的右上角添加目录结构。还挺漂亮实用的
以上是个人瞎弄,欢迎留言指教或共同摸索。^_^
/swap (交换分区): 4G
一般分配为内存的两倍或者跟内存大小一样,我机子的物理内存为4G,所以这里给交换分区的大小也是4G
/boot (boot目录): 200M~500M足矣
我分配了200M,到现在只用了40M不到
/ (根目录): 10G~50G
我们通过apt-get安装的很多软件其实都是安装到要目录的各个文件中的,所以如果这个目录如果分得太小的话,到后面会出现磁盘空间不足而无法通过apt-get安装程序的情况
/home (用户自己的主目录): 大小随便
我把剩余的全给这个目录了。这个目录用于存放用户自己的东西, 就像windows里的除C盘以外的盘一样。下次重装Ubuntu时,只需要覆盖/boot和/这两个目录就好了。
安装过程中可以断开网络,这样可以更快的体验Ubuntu。
如果安装过程联网的话,会在安装的时候联网下载一些应用和语言包,网络慢的话会等很久。
其实这些东西可以在安装完之后自行安装。所以我一般都是断网安装,安装完系统之后,在配置系统的过程中去安装语言包。
因为安装的是64位的系统,但是有些应用需要32位的库进行支持。例如adb、aapt等工具都只支持32位的,至少目前是。
所以需要安装ia32-libs
太过简单了,自己去官网下载就好。省略…
下载好Java和Android SDK之后,需要对其进行配置,加入到环境中。
运行以下命令,修改profile文件
|
|
在文件的末尾添加以下内容:
保存退出后再运行以下命令令其生效,或者注销/重启系统
|
|
重启或者注销后生效。
Unity3d桌面实在是太慢了,自从用了xfce4之后,心情大好。非常适合配置不是特别高的机器。话说我4G内存的机器,处理器也不差,用起Unity3d卡得不能忍。
运行以下命令即可
安装完成之后,在用户登录的时候,登录框右上角有一个小图标,从那里可以切换到xfce4。
有三个选项Unity3d、Unity2d和xfce4,选择之后,输入密码就可以登录了。
接下来就是对xfce4的一些配置了,如面板、快捷键、主题等,按个人喜好弄好就。
fctix的五笔比较好用,而且启动速度相对快一点
Ctrl+Alt+T直接打开终端,复制以下命令直接运行即可。
目录切换到 themes\landscape-plus\layout_partial\post, 新建文件 footer-nav.ejs
复制以下代码至 footer-nav.ejs 文件中,然后保存
|
|
打开文件 themes/landscape-plus/source/css/_partial/article.styl ,
找到article-nav-newer和article-nav-older,并按以下进行修改
|
|
打开文件 themes\landscape-plus\layout_partial\article.ejs, 并按以下位置添加代码
还是刚才那个文件 article.ejs, 删除掉以下代码,然后保存即可
完事.看看效果吧
]]>使用的代码如下
例如我们要启动B程序的MainActivity
如果启动的Activity不是MainActivity,那么我们要保证此Activity是export的。
否则会报异常java.lang.SecurityException: Permission Denial: starting Intent
而要实现Activity为export有两个办法:
在AndroidManifest中声明此Activity为export
|
|
在AndroidManifest中为此Activity添加intent-filter,类似默认的MainActivity一样
|
|
然后在A程序中
在启动外部程序的时候,同样也是可以设置启动的flag的
例如添加FLAG_ACTIVITY_NEW_TASK标识
添加这个标识,区别在于被启动的程序(DemoB)与发起启动的程序(DemoA)是否在同一个task里。
表现出来的区别就是当启动外部程序后,按home键退出到桌面,重新打开DemoA程序,
如果带有FLAG_ACTIVITY_NEW_TASK标识,则进入的是DemoA之前的界面
而如果没有带FLAG_ACTIVITY_NEW_TASK标识,则会进入到DemoB的界面当中.
打开 themes/landscape-plus/layout/_partial/article.ejs
找到以下代码
修改成如下,然后保存.
打开文件themes/landscape-plus/source/css/_partial/article.styl
在末尾添加如下代码