建立Eclipse插件镜像服务器

使用Eclipse的时候,免不了要下载插件,可以插件的服务器一般都在国外,尤其是Android开发中的ADT(Android Developer Tools)插件,因此最好自己搭建一个镜像服务器。

常见的Eclipse插件分为两种组织方式,一种使用 Eclipse的P2插件来进行组织,一种使用site.xml进行组织。我们分别进行处理。

  • Mirror based on p2 information

对于P2方式的插件,使用Eclipse的 P2 mirror tool 可以比较方便的进行插件的离线镜像。
以下载ADT为例子:

$eclipse -nosplash -verbose -application org.eclipse.equinox.p2.metadata.repository.mirrorApplication -source https://dl-ssl.google.com/android/eclipse/ -destination ./plugins

$eclipse -nosplash -verbose -application org.eclipse.equinox.p2.artifact.repository.mirrorApplication -source https://dl-ssl.google.com/android/eclipse/ -destination ./plugins

简单介绍一下,P2采用两种文件对插件进行管理,metadataartifact,其中metadata可以理解为文件的描述信息,以及索引信息。而artifact则是实实在在的插件文件了。

因此,上面的命令,第一个是下载metadata,第二个是下载artifact。请注意命令中的细微区别。

  • Mirror based on site.xml information
java -jar $eclipse_home/plugins/org.eclipse.equinox.launcher_*.jar -application org.eclipse.update.core.standaloneUpdate -command mirror -from $from -to $to
  • 本站提供的镜像地址

ADT 23.0.7(August 2015)
Eclipse 3.8 http://www.mobibrw.com/eclipse/plugins/ADT/3.8/
Eclipse 4.5 http://www.mobibrw.com/eclipse/plugins/ADT/4.5/

  • 参考链接

1.Tool for downloading eclipse plugins from update sites
2.Equinox p2 Repository Mirroring
3.Downloading Eclipse plug-in update sites for offline installation
4.Equinox/p2/Ant Tasks/Partial Mirroring/Example

C++11 error: unable to find string literal operator 'operator"

一个简单的宏

#define LOG_INFORMATION(x, ...) LOG_ME("%s:%d, "x, __FUNCTION__,__LINE__, ##__VA_ARGS__)

一直都可以正常编译,但是当启用C++11的时候,报告编译错误

error: unable to find string literal operator 'operator""x'

网上搜了一下,说是C++11要求,当字符串跟变量连接的时候,必须增加一个空格才行。因此简单修改如下即可。

#if __cplusplus < 201103L
#define LOG_INFORMATION(x, ...) LOG_ME("%s:%d, "x, __FUNCTION__,__LINE__, ##__VA_ARGS__)
#else
#define LOG_INFORMATION(x, ...) LOG_ME("%s:%d, " x, __FUNCTION__,__LINE__, ##__VA_ARGS__)
#endif

注意:在“android-ndk-r10e”中使用的GCC版本,GCC-4.9之前的版本都存在"__cplusplus"宏定义错误的问题,需要参考“NDK下GCC定义__cplusplus不正确的问题”,把GCC升级到4.9

Android 5.0 模拟器休眠唤醒(黑屏)

Android 5.0 模拟器默认在一分钟之内没有操作,就会关闭屏幕,出现黑屏的情况,如下图所示.android_simulator_black_screen

注意,这不是死掉了,只是休眠了而已。解除休眠的方式是按“ESC”或者“F7”按键即可。如果需要测试休眠的话,“F7”按键是个不错的选择。

Cura 15.04 实心打印

Cura 15.04 打印物体,默认是对打印对象进行部分填充,来节省打印耗材,但是打印一些中空的结构的时候,会出现边框强度不够的情况,导致边缘的强度非常差,这时候需要设置完全填充。如下设置即可。注意: 设置后,最好关闭一下软件重新打开,出现过修改无效的情况!

Cura_15_04_Fill

NDK 链接第三方静态库的方法

将NDK编译的第三方静态拷贝到JNI目录下,在Android.mk中添加如下代码

以openssl静态库(libcrypto-static.a)为例

第一种链接方法:LOCAL_LDFLAGS := libcrypto-static.a(不推荐,有编译警告

第二种链接方法:LOCAL_LDLIBS := libcrypto-static.a(不推荐,有编译警告

第三种链接方法:(推荐

include $(CLEAR_VARS)
LOCAL_MODULE := third_static_lib (可以随便起一个名字)
LOCAL_SRC_FILES := libcrypto-static.a
include $(PREBUILT_STATIC_LIBRARY)
//在你要编译的模块中引用third_static_lib
LOCAL_STATIC_LIBRARIES := third_static_lib

Ubuntu自动备份远程服务器上WordPress的脚本

Ubuntu 自动备份远程服务器上Wordpress的脚本,分为两部分,一个是从远程服务器上面运行的"hostback.sh",一个是本地运行的 “backup.sh”,运行的时候,"hostback.sh"会被发送到服务器上面去执行,备份完成后,会自动从服务器上面删除。
运行命令为:

$ expect backup.sh

hostback.sh

#!/bin/sh
LogFile=~/backup/backup-`date +%Y%m%d`.log                #指定日志的名字
BakDir=~/backup                            #备份文件存放的路径
MD5File=~/backup/md5-`date +%Y%m%d`.txt
Sha1File=~/backup/sha1-`date +%Y%m%d`.txt

#create backup directory

if [ -d $BakDir ]
then
    cd $BakDir
    touch $LogFile
else
    mkdir -p $BakDir
    cd $BakDir
    touch $LogFile
fi


#backup wordpress
datadump=`which mysqldump`
wordpressdb="wordpress"                                   #wordpress数据库的名字
wordpresspath=/var/www         			#wordpress程序文件的位置
mysqluser="root"                              #数据库的用户名
userpass="password"                             #用户密码
backupwordpress_tar_gz=$wordpressdb.`date +%Y%m%d`.tar.gz
backupwordpress_sql=$wordpressdb.`date +%Y%m%d`.sql

if $datadump -u $mysqluser --password=$userpass -h localhost --opt $wordpressdb > $backupwordpress_sql 2>&1
then
    echo " backup $wordpressdb success" >> $LogFile
else
    echo " backup $wordpressdb error" >> $LogFile
    exit 1
fi

#检验文件尾部是否存在 “-- Dump completed on”,如果存在不存在,则说明备份出错了。
if [ 0 -eq "$(sed '/^$/!h;$!d;g' $backupwordpress_sql | grep -c "Dump completed on")" ]; 
then
	echo " backup $wordpressdb error" >> $LogFile
	exit 1	
fi

#使用h参数的目的在于把软连接指向的实际内容打包进入,而不是仅仅打包一个软连接
if tar czpfh $backupwordpress_tar_gz $wordpresspath $backupwordpress_sql >/dev/null 2>&1
then
    echo " backup wordpress success" >> $LogFile
    rm -f $wordpressdb.`date +%Y%m%d`.sql
else
    echo " backup wordperss error" >> $LogFile
    exit 1
fi

md5sum $backupwordpress_tar_gz >> $MD5File
sha1sum $backupwordpress_tar_gz >> $Sha1File

backup.sh

#!/usr/bin/expect -f
#开启内部动作调试输出,观察是否正确执行 1 代表打开调试,0代表关闭调试
exp_internal 0
set HostAddr "www.mobibrw.com"
set HostPort 22
set UserName "user"
set BackupShell "hostback.sh"
set Password "password"
set BakDir "backup"
set timeout -1

#由于通过FTP传输的文件格式可能\n被替换为\r\n 的情况,因此需要执行一下 dos2unix 转化到 \n
spawn dos2unix $BackupShell
expect eof

spawn ssh $HostAddr -p $HostPort -l $UserName  rm -rf ~/$BackupShell 
expect -re ".*assword:" 
send "$Password\r" 
expect eof

spawn scp $BackupShell $UserName@$HostAddr:~/$BackupShell
expect -re ".*assword:" 
send "$Password\r" 
expect eof

spawn ssh $HostAddr -p $HostPort -l $UserName  chmod +x ~/$BackupShell
expect -re ".*assword:"
send "$Password\r"
expect eof 

#解决在群晖NAS系统上TCP超时问题,增加心跳保持参数
#同时注意,远端语言有可能不是英文,因此需要增加LC_ALL=C强制切换到英文,否则后续匹配可能无法完成
spawn ssh $HostAddr -o TCPKeepAlive=yes -o ServerAliveInterval=30 -p $HostPort -l $UserName "LC_ALL=C sudo -E bash ~/$BackupShell"
expect -re ".*assword:" 
send "$Password\r" 
expect eof

spawn scp -r $UserName@$HostAddr:~/$BakDir  ./
expect -re ".*assword:" 
send "$Password\r" 
expect eof

#backup-20151227.log\nbash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.utf8) 这种情况要注意
proc getFilterFile { host port user bakdir password filter regx} {
 spawn ssh $host -p $port -l $user  ls  ~/$bakdir | grep $filter
 expect -re ".*assword:"
 send "$password\r"
 expect -re "$regx"
 expect eof
 return [string trimright $expect_out(0,string)]
}

cd ./$BakDir

#校验MD5,SHA1
set MD5File [getFilterFile $HostAddr $HostPort $UserName $BakDir $Password "md5" "md5(.*).txt"]
puts stdout $MD5File

#修改语言环境,否则md5sum,sha1sum返回的结果中可能不会出现"OK",而是会出现“确定”
#“失败”
if {[info exists ::env(LANG)]==1} {
	set ORG_LANG "$env(LANG)"
	puts stdout "$env(LANG)"
	set env(LANG) "C"
	puts stdout "$env(LANG)"
}

if {[info exists ::env(LC_ALL)]==1} {
	set ORG_LC_ALL "$env(LC_ALL)"
	puts stdout "$env(LC_ALL)"
	set env(LC_ALL) "C"
	puts stdout "$env(LC_ALL)"
}

spawn md5sum -c $MD5File
expect -re ".*OK"
expect eof

set Sha1File [getFilterFile $HostAddr $HostPort $UserName $BakDir $Password "sha1" "sha1(.*).txt"]
puts stdout $Sha1File

spawn sha1sum -c $Sha1File
expect -re ".*OK"
expect eof

#还原语言设置
if {[info exists ::env(LANG)]==1} {
	puts stdout "$env(LANG)"
	set env(LANG) "$ORG_LANG"
	puts stdout "$env(LANG)"
}
if {[info exists ::env(LC_ALL)]==1} {
	puts stdout "$env(LC_ALL)"
	set env(LC_ALL) "$ORG_LC_ALL"
	puts stdout "$env(LC_ALL)"
}


#打印本次的备份日志出来
set LogFile [getFilterFile $HostAddr $HostPort $UserName $BakDir $Password "backup" "backup(.*).log"]
puts stdout $LogFile

set f [ open $LogFile r]
while { [ gets $f line ] >= 0 } { puts stdout $line;}

#删除远端的备份脚本
spawn ssh $HostAddr -p $HostPort -l $UserName sudo rm -rf ~/$BackupShell
expect -re ".*assword:" 
send "$Password\r" 
expect eof

#删除远端的备份目录
spawn ssh $HostAddr -p $HostPort -l $UserName sudo rm -rf ~/$BakDir
expect -re ".*assword:" 
send "$Password\r" 
expect eof

Windows 10下面Android模拟器无法拖动问题的解决

Windows 10下面Android模拟器往往会顶到桌面的最上面,也就是上面的最大最小关闭按钮那一栏超过屏幕的最上面的边缘,导致无法拖动。这个时候是非常痛苦的。简单的修正这个问题的办法如下:
在底层任务栏右击,点击“层叠显示窗口”就可以了。
AndroidSimulatorShow

Windows下面Android Studio提示“Can't use Subversion command line client: svn”

Windows下面Android Studio提示

Errors found while svn working copies detection. Fix it.
Can't use Subversion command line client: svn
Probably the path to Subversion executable is wrong. Fix it. (show balloon)
Can't use Subversion command line client: svn
Probably the path to Subversion executable is wrong. Fix it. (show balloon)

如果安装TortoiseSVN的时候没有选中Command Line Client的话,可能会导致上面的问题。

解决方法就是重新安装Tortoise SVN,在安装的时候选上“command line client tools”即可。
TortoiseSVNCommandLineInstall

Android模拟器, push文件到system下文件夹权限,空间,SO文件没有自动安装的问题

  • 只读文件系统

需要把APK Push到模拟器下面的 /system/app 目录下面,报告

$ adb push app-debug.apk /system/app
failed to copy 'app-debug.apk' to '/system/app/app-debug.apk': Read-only file system

解决方法

$ adb remount
  • 内存不足
$ adb push app-debug.apk /system/app
failed to copy 'app-debug.apk' to '/system/app/app-debug.apk': Out of memory

原因众说纷纭,基本上大家都没怎么深究,有些镜像没有这个问题,有些就有问题。
解决方法:
不要使用Eclipse或者Android Studio 或者 AVD Manager的图形界面去启动模拟器,而是使用下面的命令:

$Android_SDK_HOME/tools/emulator -partition-size 256 -avd "模拟器的名字"
  • 包含SO的APK启动崩溃,日志中显示无法找到SO文件

原因,Android 设计问题,如果system/app下面的APK包含SO文件,不会自动安装,需要手工PUSH 到 "/system/lib"目录下面。

  • Android 5.0之后,最好推送到/system/priv-app目录

5.0之后的Android,最好推送到/system/priv-app目录。

  • Android 5.0之后,推送到系统目录后,没有自动安装应用

原因,Android 5.0之后,没有实时监视/system/priv-app目录的变化,只有在系统启动的时候才会扫描一下(重启系统很慢,我们可以按照如下操作节约时间),因此需要手工通知一下(有时候需要修改一下权限才可以)。

$ chown 644 /system/priv-app/my-app.apk

$ adb shell am restart

Cura 14以及Cura 15 版本如何找到Cura 13中的打印机设置Temp,Jog,Speed等页面

一直使用商家提供的Cura 13进行3D打印,前段日子看到软件已经升级到了15.04版本(注意:最新的Cura 15 提供了两个版本,一个是官方的配合最新的3D打印机的版本,一个是社区版本,我们只能使用社区版本,才有下面的界面),于是下载了一个版本使用,结果发现找不到在Cura 13中调试打印机的页面了。如下图所示是Cura 13的设置页面,其中Jog主要是用来调试打印机的。Cura_13_Jog
Cura 13 之后的版本精简了打印界面,变成了这个样子,找不到原来的调试页面了。
Cura_15_Print
其实这个页面是存在的,只是被隐藏了而已,执行如下操作即可显示出来了。

  • 在“File”菜单中选择“Perferences...”菜单

Cura_15_Preferences

  • 在“Perferences”窗口中选择“Printing window type”下拉菜单,里面选择“Pronterface UI”

Cura_15_Preferences_Window

Cura_15_Preferences_Printing_Window_Type

  • 点击OK,关闭设置窗口后,点击“Print”菜单,就可以见到更加高级的打印设置界面了。

Cura_15_After_Window_Type

Cura_15_Advance_Printing_Window