[转载]Android反编译植入代码(详解,手把手)-Android开发经验分享-eoe 移动开发者论坛 - Powered by Discuz!

mikel阅读(1299)

[转载]Android反编译植入代码(详解,手把手)-Android开发经验分享-eoe 移动开发者论坛 – Powered by Discuz!.

虽然说Android的反编译一直都不是什么神秘高深的技术,好久之前就已经搞过,但是闲着无聊,还是想来跟小伙伴们分享一下。

一、工欲善其事必先利其器。

反编译apk包不可少的就是apktool工具,可以上 https://code.google.com/p/Android-apktool/ 下载相关工具,或在我的附件中下载亦可。
(apktool所依赖的环境包括JDK、Android SDK,此处不赘述)。

二、反编译植入代码的思路与方法。

  其实思路很简单,
1、假如我们要植入代码带targetapk.apk中, 那么首先我们要反编译 targetapk.apk,得到源代码对应字节码。我们知道,如果我们要植入代码到其中,必须加入字节码然后重新编译打包。
2、但是我们只会Android代码,怎么写字节码?其实我们只要新建一个Android工程,将我们需要加入的Android代码写入,然后打包成apk,比如sourceapk.apk;接着反编译它得到Android代码对应的字节码。
3、将需要植入的Android代码对应的字节码拷贝,粘贴到targetapk对应的字节码源文件中的合适位置。
4、重新编译targetapk对应的源文件,生成apk后进行签名即可安装使用。

思路出来了,方法也就呼之欲出了,接下来直接进入实战
1、apktool反编译命令:apktool d targetapk.apk targetapkfolder  。重新编译命令:apktool b targetapkfolder  。 生成的apk在targetapkfolder的dist文件夹下。
2、以金山毒霸为目标apk,植入一段Toast代码进行演示。
①反编译duba.apk:

命令行cd到apktool目录下(或者直接点击其中的start.bat即可),并将duba.apk拷贝到该目录:

     开始反编译,执行 “apktool.bat d duba.apk duba”命令:

       似乎反编译一切顺利,得到duba文件夹(关于反编译后的文件结构和格式以及字节码语法,有兴趣就去Google了解一下):

           ②编写需要植入的Android代码生成apk包,然后反编译该apk包得到代码的字节码。

  找到反编译后得到SourceApk文件夹中Toast的Android代码对应的字节码(代码包在 smali文件夹下):

③将得到的Toast代码对应的字节码复制,粘贴到金山毒霸的主界面代码中:

通过反编译后的duba文件夹中的AndroidManifest.xml可以找到主界面对应的类所在位置:
(我们暂且将代码放到毒霸的splash界面也无妨)

接着找到SplashActivity.smali中的setContentView,在其下面加入Toast字节码:

       ④保存后重新编译duba文件夹,执行 “apktool.bat b duba”命令:

            貌似重新编译一切顺利(可能一些apk会出现千奇百怪的错误,那就Google吧),找到植入代码后的duba.apk :

           ⑤得到植入代码后的duba.apk为未签名apk,需经过签名后才可安装使用。
(关于apk签名,此处不多加赘述,不懂的就Google去吧。或者使用附件中的签名工具进行Debug签名)


          ⑥签完名可以安装使用了,看看是否成功吧:

三、关于反编译的总结与后续。

      1、相信大家看了我的示例会觉得原来反编译这么简单。其实对于大部分Apk来说反编译都是这么简单,只要抓对思路。
2、本例中只是示范了一个简单得不能再简单的反编译植入代码的示例,其实一般反编译大多用于App的破解、App的汉化、App植入广告等(个人觉得)。
3、本来想着写完这个入门级的示例后,再写个植入广告的示例的。But,我现在已经无力再继续写了,下次吧。其实掌握思路之后,用apktool工具都可以很简单做到。
4、有兴趣了解更多的,可以去看我上一个”关于小米手机抢购页面代码分析“的贴,上面有个技术交流群号,可以在群上面找到我。


四、那些年调戏过的App。




   
      


apktool-1.5.2_with_signtool.zip

2.8 MB, 下载次数: 161

 

反编译工具+apk签名工具

[转载]nginx 504 Gateway Time-out错误解决办法

mikel阅读(1047)

[转载]nginx 504 Gateway Time-out错误解决办法.我们经常会发现大量的nginx服务器访问时会提示nginx 504 Gateway Time-out错误了,下面我来总结了一些解决办法,有需要了解的同学可进入参考。

一般看来, 这种情况可能是由于nginx默认的fastcgi进程响应的缓冲区太小造成的, 这将导致fastcgi进程被挂起, 如果你的fastcgi服务对这个挂起处理的不好, 那么最后就极有可能导致504 Gateway Time-out
现在的网站, 尤其某些论坛有大量的回复和很多内容的, 一个页面甚至有几百K
默认的fastcgi进程响应的缓冲区是8K, 我们可以设置大点

在nginx.conf里, 加入:

fastcgi_buffers 8 128k

这表示设置fastcgi缓冲区为8×128k
当然如果您在进行某一项即时的操作, 可能需要nginx的超时参数调大点, 例如设置成60秒:

send_timeout 60;

我只是调整了这两个参数, 结果就是没有再显示那个超时, 可以说效果不错

另一篇文章

首先是更改php-fpm的几处配置:

把max_children由之前的10改为现在的30,这样就可以保证 有充足的php-cgi进程可以被使用;

request_terminate_timeout由之前的0s改为60s,这样php-cgi进程 处理脚本的超时时间就是60秒,可以防止进程都被挂起,提高利用效率。

接着再更改nginx的几个配置项,减少FastCGI的请求次 数,尽量维持buffers不变:

fastcgi_buffers由 4 64k 改为 2 256k;
fastcgi_buffer_size 由 64k 改为 128K;
fastcgi_busy_buffers_size 由 128K 改为 256K;
fastcgi_temp_file_write_size 由 128K 改为 256K。

好了,重新加载php-fpm和nginx的配置,再次测试,至今两周时间内没有再出现504 Gateway Time-out的情况,算是达到效果了。

另外,php-fpm的默认静态处理方式会使得php-cgi的进程长期占用内存而无法释放,这也是导致nginx出错的原因之一,因此可以将php-fpm的处理方式改成apache模式。
apache-like

[转载]android 自定义适配器 - clarence_123 - 博客园

mikel阅读(1006)

[转载]android 自定义适配器 – clarence_123 – 博客园.应用程序实体类

public class App{

private int appId; // 应用程序id

private String appName;// 应用程序名称

private String appIcon; // 应用程序图标

public int getAppId(){ return this.appId; }

public void setAppId(){ this.appId=value; }

public int getAppName(){ return this.appName; }

public void setAppName(){ this.appId=appName; }

public int getAppIcon(){ return this.appIcon; }

public void setAppIcon(){ this.appId=appIcon; }

}

app_item.xml 文件

<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:Android=”http://schemas.Android.com/apk/res/Android
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”>

<ImageView
android:id=”@+id/imgIcon”
android:layout_width=”50px”
android:layout_height=”50px”
android:layout_alignParentLeft=”true”
android:layout_alignParentTop=”true”
android:layout_marginLeft=”5dip”
android:layout_marginTop=”2dip”
android:src=”@drawable/portrait” />

<TextView
android:id=”@+id/txtName”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”10dip”
android:layout_centerVertical=”true”
android:layout_toRightOf=”@id/imgPortrait”
android:textColor=”@android:color/black”
android:textSize=”16dip”
android:gravity=”center”
android:text=”” />

<Button
android:id=”@+id/btnDel”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentRight=”true”
android:layout_centerVertical=”true”
android:layout_marginRight=”10dip”

android:text=”删除”
android:textSize=”12dip”
android:focusable=”false”
android:focusableInTouchMode=”false” />

// 注意:当设置 android:focusable=”false” 和 android:focusableInTouchMode=”false” 时,可避免和ListView的Item点击事件冲突,导致item的click事件无效。

</RelativeLayout>

自定义数据适配器

public class AppAdapter extends BaseAdapter implements View.OnClickListener {

private Context context;
private List<App> appList;
private final String inflater = Context.LAYOUT_INFLATER_SERVICE;
private LayoutInflater layoutInflater;
private Handler handler;

private AsyncImageLoader imageLoader; // 异步加载图片的类

// 视图容器类,属性对应布局文件元素

private class ViewHolder {
ImageView imgIcon;
TextView txtName;
Button btnDel;
}

// 构造函数

public AppAdapter (Context c, List<App> list) {
if (null != list) {
appList= list;
} else {
appList= new ArrayList<App>();
}
this.context = c;
layoutInflater = (LayoutInflater) context.getSystemService(inflater);

handler = new Handler();

imageLoader = new AsyncImageLoader();
}

// 添加单个项(自定义方法)

public void addItem(App item) {
if (item != null) {
appList.add(item);
notifyDataSetChanged(); // 通知适配器数据已改变
}
}

// 添加多个项(自定义方法)

public void addItem(List<App> list) {
if (null != list && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
appList.add(list.get(i));
}
notifyDataSetChanged(); // 通知适配器数据已改变

}
}

// 删除项(自定义方法)

public void removeItem(int position) {
if (appList.get(position) != null) {
appList.remove(position);
notifyDataSetChanged(); // 通知适配器数据已改变
}
}

// 获取总数

public int getCount() {
return appList.size();
}

// 获取单条数据

public App getItem(int position) {

return appList.get(position);
}

// 获取当前位置项的id(自定义方法)

public int getItemId(int position) {

return appList.get(position).getAppId();
}

// 获取视图

public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (null == convertView) {
// 装载布局文件 app_item.xml
convertView = (RelativeLayout) layoutInflater.inflate(R.layout.app_item, null);
holder = new ViewHolder();

holder.imgIcon = (ImageView) convertView.findViewById(R.id.imgIcon );
holder.txtNick = (TextView) convertView.findViewById(R.id.txtNick );
holder.btnDel= (Button) convertView.findViewById(R.id.btnDel);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
App app = appList.get(position); // 获取当前项数据
if (null != app) {
holder.txtName.setText(app.getAppName());

holder.btnDel.setOnClickListener(this); // 添加按钮点击事件

holder.btnDel.setTag(app.getAppId()); // 设置按钮”tag”为应用程序的id,便于删除时使用

imageLoader.loadImage(app.getAppIcon(), holder.imgIcon); // 异步加载图片
}
return convertView;
}

// 实现 View.OnClickListener 接口方法

public void onClick(View v) {
Button btn = (Button) v;

// 获取当前删除项的id
int id= Integer.parseInt(btn.getTag().toString());

// 调用删除方法

removeItem(id);

}
}

在Activity类中调用如下:

List<App> list = new List<App>(); // 获取数据

AppAdapter adapter = new AppAdapter(this, list );

listView.setAdapter(adapter); // listView 为 ListView 对象实例

[转载]干货分享 超炫丽的HTML5/jQuery应用及代码 - html5tricks - 博客园

mikel阅读(1704)

[转载]干货分享 超炫丽的HTML5/jQuery应用及代码 – html5tricks – 博客园.

今天我们要来分享一些HTML5干货,对于前段开发者来说,这些HTML5应用和JQuery插件将会让你的项目更加生动和炫丽,至少在UI设计方面,或多或少会带给你一点设计灵感,赶紧收藏和分享吧。另外这些HTML5应用的源代码也一并分享了。

HTML5 Canvas画板画图工具 可定义笔刷和画布

这是一款基于HTML5 Canvas的网络画板应用,简化版的,可以自己在上面扩展。

核心JQuery代码:

function prepareCanvas()
{
// Create the canvas (Neccessary for IE because it doesn't know what a canvas element is)
var canvasDiv = document.getElementById('canvasDiv');
canvas = document.createElement('canvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if(typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d"); // Grab the 2d canvas context
// Note: The above code is a workaround for IE 8 and lower. Otherwise we could have used:
// context = document.getElementById('canvas').getContext("2d");

// Load images
// -----------
crayonImage.onload = function() { resourceLoaded();
};
crayonImage.src = "images/crayon-outline.png";
//context.drawImage(crayonImage, 0, 0, 100, 100);

markerImage.onload = function() { resourceLoaded();
};
markerImage.src = "images/marker-outline.png";

eraserImage.onload = function() { resourceLoaded();
};
eraserImage.src = "images/eraser-outline.png";

crayonBackgroundImage.onload = function() { resourceLoaded();
};
crayonBackgroundImage.src = "images/crayon-background.png";

markerBackgroundImage.onload = function() { resourceLoaded();
};
markerBackgroundImage.src = "images/marker-background.png";

eraserBackgroundImage.onload = function() { resourceLoaded();
};
eraserBackgroundImage.src = "images/eraser-background.png";

crayonTextureImage.onload = function() { resourceLoaded();
};
crayonTextureImage.src = "images/crayon-texture.png";

outlineImage.onload = function() { resourceLoaded();
};
outlineImage.src = "images/watermelon-duck-outline.png";

// Add mouse events
// ----------------
$('#canvas').mousedown(function(e)
{
// Mouse down location
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;

if(mouseX &lt; drawingAreaX) // Left of the drawing area { if(mouseX &gt; mediumStartX)
{
if(mouseY &gt; mediumStartY &amp;&amp; mouseY &lt; mediumStartY + mediumImageHeight){ curColor = colorPurple; }else if(mouseY &gt; mediumStartY + mediumImageHeight &amp;&amp; mouseY &lt; mediumStartY + mediumImageHeight * 2){ curColor = colorGreen; }else if(mouseY &gt; mediumStartY + mediumImageHeight * 2 &amp;&amp; mouseY &lt; mediumStartY + mediumImageHeight * 3){ curColor = colorYellow; }else if(mouseY &gt; mediumStartY + mediumImageHeight * 3 &amp;&amp; mouseY &lt; mediumStartY + mediumImageHeight * 4){ curColor = colorBrown; } } } else if(mouseX &gt; drawingAreaX + drawingAreaWidth) // Right of the drawing area
{
if(mouseY &gt; toolHotspotStartY)
{
if(mouseY &gt; sizeHotspotStartY)
{
var sizeHotspotStartX = drawingAreaX + drawingAreaWidth;
if(mouseY &lt; sizeHotspotStartY + sizeHotspotHeight &amp;&amp; mouseX &gt; sizeHotspotStartX)
{
if(mouseX &lt; sizeHotspotStartX + sizeHotspotWidthObject.huge){
curSize = "huge";
}else if(mouseX &lt; sizeHotspotStartX + sizeHotspotWidthObject.large + sizeHotspotWidthObject.huge){
curSize = "large";
}else if(mouseX &lt; sizeHotspotStartX + sizeHotspotWidthObject.normal + sizeHotspotWidthObject.large + sizeHotspotWidthObject.huge){
curSize = "normal";
}else if(mouseX &lt; sizeHotspotStartX + sizeHotspotWidthObject.small + sizeHotspotWidthObject.normal + sizeHotspotWidthObject.large + sizeHotspotWidthObject.huge){
curSize = "small";
}
}
}
else
{
if(mouseY &lt; toolHotspotStartY + toolHotspotHeight){
curTool = "crayon";
}else if(mouseY &lt; toolHotspotStartY + toolHotspotHeight * 2){
curTool = "marker";
}else if(mouseY &lt; toolHotspotStartY + toolHotspotHeight * 3){ curTool = "eraser"; } } } } else if(mouseY &gt; drawingAreaY &amp;&amp; mouseY &lt; drawingAreaY + drawingAreaHeight)
{
// Mouse click location on drawing area
}
paint = true;
addClick(mouseX, mouseY, false);
redraw();
});

$('#canvas').mousemove(function(e){
if(paint==true){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});

$('#canvas').mouseup(function(e){
paint = false;
redraw();
});

$('#canvas').mouseleave(function(e){
paint = false;
});
}

html5-canvas-draw

在线演示        源码下载

HTML5/CSS3滑块动画菜单 图标动画很酷

非常实用的鼠标跟随滑动菜单,挺不错的。

核心CSS代码:

#menu ul{
position:relative;
}
#menu ul:after{
content:"";
display:block;
clear:both;
}
#menu a{
color:#D8D8D8;
text-decoration:none;
display:block;
width:100%;
height:100%;
text-shadow: 0 -1px 0 #000;
}
#menu li:after {
content: "";
width: 9.5238%;
height: 100%;
position: absolute;
top: 0;
right: -9.5238%;
background: url('css/menu-bg.png');
}
.rocket:before {
content: "";
width: 9.5238%;
height: 100%;
position: absolute;
top: 0;
left: -9.5238%;
background: url('css/menu-bg.png');
border-radius: 5px 0px 0px 5px;
}
.earth:after{
border-radius:0px 5px 5px 0px;
}
.current{
position:absolute;
top:-13px;
left:8.92857%;
margin-left: -49px;
width:95px;
height:165px;
-webkit-transition: all 400ms cubic-bezier(.45,1.92,.9,1.54);
-moz-transition: all 400ms cubic-bezier(.45,1.92,.9,1.54);
-o-transition: all 400ms cubic-bezier(.45,1.92,.9,1.54);
-ms-transition: all 400ms cubic-bezier(.45,1.92,.9,1.54);
transition: all 400ms cubic-bezier(.16,1.23,.87,1.18);
}
.current-back{
width:100%;
height:100%;
position:absolute;
background:#c39449;
border-radius:5px;
border-bottom: 2px solid rgba(0, 0, 0, 0.09);
border-top: 2px solid rgba(255,255,255,0.1);
}
.top-arrow{
position:absolute;
overflow:hidden;
width:100%;
height:12px;
top:13px;
left:0;
z-index:2;
}
.top-arrow:before{
content:"";
position:absolute;
width:80%;
height:10px;
top:-10px;
left:10%;
border-radius:20%;
box-shadow:0 0 10px black;
}
.top-arrow:after{
content:"";
position:absolute;
width:0;
height:0;
top:0px;
border-top:8px solid #c39449;
border-left:6px solid transparent;
border-right:6px solid transparent;
margin-left:-6px;
left:50%;
}

.bottom-arrow{
position:absolute;
overflow:hidden;
width:100%;
height:12px;
bottom:17px;
left:0;
z-index:2;
}
.bottom-arrow:before{
content:"";
position:absolute;
width:80%;
height:10px;
bottom:-10px;
left:10%;
border-radius:20%;
box-shadow:0 0 10px black;
}
.bottom-arrow:after{
content:"";
position:absolute;
width:0;
height:0;
bottom:0;
border-bottom:12px solid #c39449;
border-left:8px solid transparent;
border-right:8px solid transparent;
margin-left:-8px;
left:50%;
}

.wine:hover ~ .current{
left: 25.5%;
}
.burger:hover ~ .current{
left: 42%;
}
.comment:hover ~ .current{
left: 58.5%;
}
.sport:hover ~ .current{
left: 75%;
}
.earth:hover ~ .current{
left: 91.1%;
}

html5-css3-fluid-menu-with-icon

在线演示        源码下载

HTML5/CSS3 3D文字特效 文字外翻效果

一款基于HTML5的3D文字特效。

核心CSS代码:

.letter{
display: inline-block;
font-weight: 900;
font-size: 8em;
margin: 0.2em;
position: relative;
color: #00B4F1;
transform-style: preserve-3d;
perspective: 400;
z-index: 1;
}
.letter:before, .letter:after{
position:absolute;
content: attr(data-letter);
transform-origin: top left;
top:0;
left:0;
}
.letter, .letter:before, .letter:after{
transition: all 0.3s ease-in-out;
}
.letter:before{
color: #fff;
text-shadow:
-1px 0px 1px rgba(255,255,255,.8),
1px 0px 1px rgba(0,0,0,.8);
z-index: 3;
transform:
rotateX(0deg)
rotateY(-15deg)
rotateZ(0deg);
}
.letter:after{
color: rgba(0,0,0,.11);
z-index:2;
transform:
scale(1.08,1)
rotateX(0deg)
rotateY(0deg)
rotateZ(0deg)
skew(0deg,1deg);
}
.letter:hover:before{
color: #fafafa;
transform:
rotateX(0deg)
rotateY(-40deg)
rotateZ(0deg);
}
.letter:hover:after{
transform:
scale(1.08,1)
rotateX(0deg)
rotateY(40deg)
rotateZ(0deg)
skew(0deg,22deg);
}

html5-3d-letter-text

在线演示        源码下载

CSS3波浪形菜单 结合背景超级绚丽

一款非常具有创意的CSS3菜单,波浪形状的。

核心CSS代码:

.b-nav {
overflow: hidden;
position: relative;
margin: 3em auto 0;
width: 28em; height: 10em;
}
.b-menu {
width: 0; height: 0;
list-style: none;
}
.b-menu li {
overflow: hidden;
position: absolute;
width: 12em; height: 12em;
}
.b-menu li:nth-child(-n+3) {
top: 0.66em; left: -5.68em;
transform-origin: 100% 100%;
}
.b-menu li:nth-child(n+4) {
right: -5.69em; bottom: 0.66em;
transform-origin: 0 0;
}
.b-menu li:first-child {
transform: skewY(67.5deg);
}
.b-menu li:nth-child(2) {
transform: rotate(22.5deg) skewY(67.5deg);
}
.b-menu li:nth-child(3) {
transform: rotate(45deg) skewY(67.5deg);
}
.b-menu li:nth-child(4) {
transform: skewY(67.5deg);
}
.b-menu li:nth-child(5) {
transform: rotate(22.5deg) skewY(67.5deg);
}
.b-menu li:last-child {
transform: rotate(45deg) skewY(67.5deg);
}
.b-menu a, .b-menu li:after {
position: absolute;
border-radius: 50%;
box-shadow: 0 0 .2em black, inset 0 0 .2em black;
transform: skewY(-67.5deg) rotate(-11.25deg);
}
.b-menu a {
width: 200%; height: 200%;
opacity: .7;
background: radial-gradient(transparent 57.3%,
#c9c9c9 57.7%);
color: #7a8092;
font: 900 1em/2.5 sans-serif;
text-align: center;
text-decoration: none;
transition: .5s;
}
.b-menu li:nth-child(n+4) a {
top: -100%; left: -100%;
line-height: 45.5;
}
.b-menu a:hover { opacity: 1; }
.b-menu li:after {
top: 19%; left: 19%;
width: 162%; height: 162%;
content: '';
}
.b-menu li:nth-child(n+4):after {
top: auto; right: 19%; bottom: 19%; left: auto;
}
.b-menu:before, .b-menu:after {
position: absolute;
width: 1em; height: 2.1em;
opacity: .7;
background: #c9c9c9;
content: '';
}
.b-menu:before {
top: 1.75em; left: 1.21em;
border-radius: 100% 0 0 100%/ 50% 0 0 50%;
transform: rotate(-22.5deg);
}
.b-menu:after {
bottom: 1.75em; right: 1.21em;
border-radius: 0 100% 100% 0/ 0 50% 50% 0;
transform: rotate(-22.5deg);
}

css3-wave-menu

在线演示        源码下载

HTML5/CSS3时尚的圆盘时钟动画 带当前日期

又是一款HTML5圆盘时钟动画。

核心CSS代码:

#watch .minute-marks li:first-child {transform:rotate(6deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(2) {transform:rotate(12deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(3) {transform:rotate(18deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(4) {transform:rotate(24deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(5) {transform:rotate(36deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(6) {transform:rotate(42deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(7) {transform:rotate(48deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(8) {transform:rotate(54deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(9) {transform:rotate(66deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(10) {transform:rotate(72deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(11) {transform:rotate(78deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(12) {transform:rotate(84deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(13) {transform:rotate(96deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(14) {transform:rotate(102deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(15) {transform:rotate(108deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(16) {transform:rotate(114deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(17) {transform:rotate(126deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(18) {transform:rotate(132deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(19) {transform:rotate(138deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(20) {transform:rotate(144deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(21) {transform:rotate(156deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(22) {transform:rotate(162deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(23) {transform:rotate(168deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(24) {transform:rotate(174deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(25) {transform:rotate(186deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(26) {transform:rotate(192deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(27) {transform:rotate(198deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(28) {transform:rotate(204deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(29) {transform:rotate(216deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(30) {transform:rotate(222deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(31) {transform:rotate(228deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(32) {transform:rotate(234deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(33) {transform:rotate(246deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(34) {transform:rotate(252deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(35) {transform:rotate(258deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(36) {transform:rotate(264deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(37) {transform:rotate(276deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(38) {transform:rotate(282deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(39) {transform:rotate(288deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(40) {transform:rotate(294deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(41) {transform:rotate(306deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(42) {transform:rotate(312deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(43) {transform:rotate(318deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(44) {transform:rotate(324deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(45) {transform:rotate(336deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(46) {transform:rotate(342deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(47) {transform:rotate(348deg) translateY(-12.7em)}
#watch .minute-marks li:nth-child(48) {transform:rotate(354deg) translateY(-12.7em)}
#watch .digits {
width:30em;
height:30em;
border-radius:15em;
position:absolute;
top:0; left:50%;
margin-left:-15em;
}
#watch .digits li {
font-size:1.6em;
display:block;
width:1.6em;
height:1.6em;
position:absolute;
top:50%; left:50%;
line-height:1.6em;
text-align:center;
margin:-.8em 0 0 -.8em;
font-weight:bold;
}
#watch .digits li:nth-child(1) { transform:translate(3.9em, -6.9em) }
#watch .digits li:nth-child(2) { transform:translate(6.9em, -4em) }
#watch .digits li:nth-child(3) { transform:translate(8em, 0) }
#watch .digits li:nth-child(4) { transform:translate(6.8em, 4em) }
#watch .digits li:nth-child(5) { transform:translate(3.9em, 6.9em) }
#watch .digits li:nth-child(6) { transform:translate(0, 8em) }
#watch .digits li:nth-child(7) { transform:translate(-3.9em, 6.9em) }
#watch .digits li:nth-child(8) { transform:translate(-6.8em, 4em) }
#watch .digits li:nth-child(9) { transform:translate(-8em, 0) }
#watch .digits li:nth-child(10) { transform:translate(-6.9em, -4em) }
#watch .digits li:nth-child(11) { transform:translate(-3.9em, -6.9em) }
#watch .digits li:nth-child(12) { transform:translate(0, -8em) }
#watch .digits:before {
content:'';
width:1.6em;
height:1.6em;
border-radius:.8em;
position:absolute;
top:50%; left:50%;
margin:-.8em 0 0 -.8em;
background:#121314;
}
#watch .digits:after {
content:'';
width:4em;
height:4em;
border-radius:2.2em;
position:absolute;
top:50%; left:50%;
margin:-2.1em 0 0 -2.1em;
border:.1em solid #c6c6c6;
background:-webkit-radial-gradient(center, ellipse cover, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%);
background:-moz-radial-gradient(center, ellipse cover, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%);
background:radial-gradient(ellipse at center, rgba(200,200,200,0), rgba(190,190,190,1) 90%, rgba(130,130,130,1) 100%);
}
@keyframes hours { to {transform:rotate(335deg)} }
#watch .hours-hand {
width:.8em;
height:7em;
border-radius:0 0 .9em .9em;
background:#232425;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -.8em -.4em;
box-shadow:#232425 0 0 2px;
transform-origin:0.4em 6.2em;
transform:rotate(-25deg);
animation:hours 43200s linear 0s infinite;
}
#watch .hours-hand:before {
content:'';
background:inherit;
width:1.8em;
height:.8em;
border-radius:0 0 .8em .8em;
box-shadow:#232425 0 0 1px;
position:absolute;
top:-.7em; left:-.5em;
}
#watch .hours-hand:after {
content:'';
width:0; height:0;
border:.9em solid #232425;
border-width:0 .9em 2.4em .9em;
border-left-color:transparent;
border-right-color:transparent;
position:absolute;
top:-3.1em; left:-.5em;
}
@keyframes minutes { to {transform:rotate(422deg)} }
#watch .minutes-hand {
width:.8em;
height:12.5em;
border-radius:.5em;
background:#343536;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -1.5em -.4em;
box-shadow:#343536 0 0 2px;
transform-origin:0.4em 11em;
transform:rotate(62deg);
animation:minutes 3600s linear 0s infinite;
}
@keyframes seconds { to {transform:rotate(480deg)} }
#watch .seconds-hand {
width:.2em;
height:14em;
border-radius:.1em .1em 0 0/10em 10em 0 0;
background:#c00;
position:absolute;
bottom:50%; left:50%;
margin:0 0 -2em -.1em;
box-shadow:rgba(0,0,0,.8) 0 0 .2em;
transform-origin:0.1em 12em;
transform:rotate(120deg);
animation:seconds 60s steps(60, end) 0s infinite;
}
#watch .seconds-hand:after {
content:'';
width:1.4em;
height:1.4em;
border-radius:.7em;
background:inherit;
position:absolute;
left:-.65em; bottom:1.35em;
}
#watch .seconds-hand:before {
content:'';
width:.8em;
height:3em;
border-radius:.2em .2em .4em .4em/.2em .2em 2em 2em;
box-shadow:rgba(0,0,0,.8) 0 0 .2em;
background:inherit;
position:absolute;
left:-.35em; bottom:-3em;
}
#watch .digital-wrap {
width:9em;
height:3em;
border:.1em solid #222;
border-radius:.2em;
position:absolute;
top:50%; left:50%;
margin:3em 0 0 -4.5em;
overflow:hidden;
background:#4c4c4c;
background:-webkit-linear-gradient(top, #4c4c4c 0%,#0f0f0f 100%);
background:-moz-linear-gradient(top, #4c4c4c 0%, #0f0f0f 100%);
background:-ms-linear-gradient(top, #4c4c4c 0%,#0f0f0f 100%);
background:-o-linear-gradient(top, #4c4c4c 0%,#0f0f0f 100%);
background:linear-gradient(to bottom, #4c4c4c 0%,#0f0f0f 100%);
}
#watch .digital-wrap ul {
float:left;
width:2.85em;
height:3em;
border-right:.1em solid #000;
color:#ddd;
font-family:Consolas, monaco, monospace;
}
#watch .digital-wrap ul:last-child { border:none }
#watch .digital-wrap li {
font-size:1.5em;
line-height:2;
letter-spacing:2px;
text-align:center;
position:relative;
left:1px;
}
#watch .digit-minutes li {
animation:dsm 3600s steps(60, end) 0s infinite;
}
#watch .digit-seconds li {
animation:dsm 60s steps(60, end) 0s infinite;
}
@keyframes dsm {
to { transform:translateY(-120em) }
}

html5-css3-clock-with-date

在线演示        源码下载

CSS3带图标提示插件 多主题颜色

一款基于CSS3样式提示框插件,色彩比较丰富。

css3-notification

在线演示        源码下载

CSS3漂亮的自定义checkbox复选框 9款迷人样式

很酷的CSS3自定义checkbox插件,样式很丰富。

html5-css3-checkbox-styles

在线演示        源码下载

HTML5/CSS3发光搜索表单 超酷CSS3表单

html5-css3-shine-search-form

在线演示        源码下载

CSS3悬停动画工具提示效果

5454

在线演示        源码下载

HTML5自定义Checkbox和Radiobox 很酷的选中动画

非常不错的一款HTML5 教程,可以让你自定义checkbox和radiobox。

核心CSS代码:

.check-box {
width: 22px;
height: 22px;
cursor: pointer;
display: inline-block;
margin: 2px 7px 0 0;
position: relative;
overflow: hidden;
box-shadow: 0 0 1px #ccc;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: rgb(255, 255, 255);
background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(47%, rgba(246, 246, 246, 1)), color-stop(100%, rgba(237, 237, 237, 1)));
background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ededed', GradientType=0);
border: 1px solid #ccc;
}
.check-box i {
background: url('css/check_mark.png') no-repeat center center;
position: absolute;
left: 3px;
bottom: -15px;
width: 16px;
height: 16px;
opacity: .5;
-webkit-transition: all 400ms ease-in-out;
-moz-transition: all 400ms ease-in-out;
-o-transition: all 400ms ease-in-out;
transition: all 400ms ease-in-out;
-webkit-transform:rotateZ(-180deg);
-moz-transform:rotateZ(-180deg);
-o-transform:rotateZ(-180deg);
transform:rotateZ(-180deg);
}
.checkedBox {
-moz-box-shadow: inset 0 0 5px 1px #ccc;
-webkit-box-shadow: inset 0 0 5px 1px #ccc;
box-shadow: inset 0 0 5px 1px #ccc;
border-bottom-color: #fff;
}
.checkedBox i {
bottom: 2px;
-webkit-transform:rotateZ(0deg);
-moz-transform:rotateZ(0deg);
-o-transform:rotateZ(0deg);
transform:rotateZ(0deg);
}
/*Custom radio button*/
.radio-btn {
width: 20px;
height: 20px;
display: inline-block;
float: left;
margin: 3px 7px 0 0;
cursor: pointer;
position: relative;
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
border-radius: 100%;
border: 1px solid #ccc;
box-shadow: 0 0 1px #ccc;
background: rgb(255, 255, 255);
background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(47%, rgba(246, 246, 246, 1)), color-stop(100%, rgba(237, 237, 237, 1)));
background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(246, 246, 246, 1) 47%, rgba(237, 237, 237, 1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ededed', GradientType=0);
}
.checkedRadio {
-moz-box-shadow: inset 0 0 5px 1px #ccc;
-webkit-box-shadow: inset 0 0 5px 1px #ccc;
box-shadow: inset 0 0 5px 1px #ccc;
}
.radio-btn i {
border: 1px solid #E1E2E4;
width: 10px;
height: 10px;
position: absolute;
left: 4px;
top: 4px;
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
border-radius: 100%;
}
.checkedRadio i {
background-color: #898A8C;
}

htm5-custom-checkbox-radio

在线演示        源码下载

CSS3联系表单 背景透明迷人

这款CSS3联系表单的背景相当不错,而且是半透明的。

核心CSS代码:

body {
background:#2d3b36 url(Blurry-city-lights1337.jpg)no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
padding-top:20px;
}

form {
margin-left:auto;
margin-right:auto;
width: 343px;
height: 333px;
padding:30px;
border: 1px solid rgba(0,0,0,.2);
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
background: rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 0 13px 3px rgba(0,0,0,.5);
-webkit-box-shadow: 0 0 13px 3px rgba(0,0,0,.5);
box-shadow: 0 0 13px 3px rgba(0,0,0,.5);
overflow: hidden;
}

textarea{
background: rgba(255, 255, 255, 0.4) url(http://luismruiz.com/img/gemicon_message.png) no-repeat scroll 16px 16px;
width: 276px;
height: 110px;
border: 1px solid rgba(255,255,255,.6);
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
display:block;
font-family: 'Source Sans Pro', sans-serif;
font-size:18px;
color:#fff;
padding-left:45px;
padding-right:20px;
padding-top:12px;
margin-bottom:20px;
overflow:hidden;
}

input {
width: 276px;
height: 48px;
border: 1px solid rgba(255,255,255,.4);
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
display:block;
font-family: 'Source Sans Pro', sans-serif;
font-size:18px;
color:#fff;
padding-left:20px;
padding-right:20px;
margin-bottom:20px;
}

input[type=submit] {
cursor:pointer;
}

input.name {
background: rgba(255, 255, 255, 0.4) url(http://luismruiz.com/img/gemicon_name.png) no-repeat scroll 16px 16px;
padding-left:45px;
}

input.email {
background: rgba(255, 255, 255, 0.4) url(http://luismruiz.com/img/gemicon_email.png) no-repeat scroll 16px 20px;
padding-left:45px;
}

input.message {
background: rgba(255, 255, 255, 0.4) url(http://luismruiz.com/img/gemicon_message.png) no-repeat scroll 16px 16px;
padding-left:45px;
}

::-webkit-input-placeholder {
color: #fff;
}

:-moz-placeholder{
color: #fff;
}

::-moz-placeholder {
color: #fff;
}

:-ms-input-placeholder {
color: #fff;
}

input:focus, textarea:focus {
background-color: rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 0 5px 1px rgba(255,255,255,.5);
-webkit-box-shadow: 0 0 5px 1px rgba(255,255,255,.5);
box-shadow: 0 0 5px 1px rgba(255,255,255,.5);
overflow: hidden;
}

.btn {
width: 138px;
height: 44px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
float:right;
border: 1px solid #253737;
background: #416b68;
background: -webkit-gradient(linear, left top, left bottom, from(#6da5a3), to(#416b68));
background: -webkit-linear-gradient(top, #6da5a3, #416b68);
background: -moz-linear-gradient(top, #6da5a3, #416b68);
background: -ms-linear-gradient(top, #6da5a3, #416b68);
background: -o-linear-gradient(top, #6da5a3, #416b68);
background-image: -ms-linear-gradient(top, #6da5a3 0%, #416b68 100%);
padding: 10.5px 21px;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
-webkit-box-shadow: rgba(255,255,255,0.1) 0 1px 0, inset rgba(255,255,255,0.7) 0 1px 0;
-moz-box-shadow: rgba(255,255,255,0.1) 0 1px 0, inset rgba(255,255,255,0.7) 0 1px 0;
box-shadow: rgba(255,255,255,0.1) 0 1px 0, inset rgba(255,255,255,0.7) 0 1px 0;
text-shadow: #333333 0 1px 0;
color: #e1e1e1;
}

.btn:hover {
border: 1px solid #253737;
text-shadow: #333333 0 1px 0;
background: #416b68;
background: -webkit-gradient(linear, left top, left bottom, from(#77b2b0), to(#416b68));
background: -webkit-linear-gradient(top, #77b2b0, #416b68);
background: -moz-linear-gradient(top, #77b2b0, #416b68);
background: -ms-linear-gradient(top, #77b2b0, #416b68);
background: -o-linear-gradient(top, #77b2b0, #416b68);
background-image: -ms-linear-gradient(top, #77b2b0 0%, #416b68 100%);
color: #fff;
}

.btn:active {
margin-top:1px;
text-shadow: #333333 0 -1px 0;
border: 1px solid #253737;
background: #6da5a3;
background: -webkit-gradient(linear, left top, left bottom, from(#416b68), to(#416b68));
background: -webkit-linear-gradient(top, #416b68, #609391);
background: -moz-linear-gradient(top, #416b68, #6da5a3);
background: -ms-linear-gradient(top, #416b68, #6da5a3);
background: -o-linear-gradient(top, #416b68, #6da5a3);
background-image: -ms-linear-gradient(top, #416b68 0%, #6da5a3 100%);
color: #fff;
-webkit-box-shadow: rgba(255,255,255,0) 0 1px 0, inset rgba(255,255,255,0.7) 0 1px 0;
-moz-box-shadow: rgba(255,255,255,0) 0 1px 0, inset rgba(255,255,255,0.7) 0 1px 0;
box-shadow: rgba(255,255,255,0) 0 1px 0, inset rgba(255,255,255,0.7) 0 1px 0;
}

css3-transparent-contact-form

在线演示        源码下载

[转载]Genymotion配置及使用教程(最新最完整版附各部分下载地址) - 代码改变世界 - 博客频道 - CSDN.NET

mikel阅读(1030)

[转载]Genymotion配置及使用教程(最新最完整版附各部分下载地址) – 代码改变世界 – 博客频道 – CSDN.NET.

早都听说了Genymotion好用,今天才抽空把他配置出来,过程算是很曲折啊,不过好在完成了。而且我发现网上的教程都不怎么全,我还是找了好几篇文章才把他完整的配置出来,这篇是我从下载到项目运行成功的所有过程,希望对大家有所帮助。闲话到此结束。

 

首先第一步:注册Genymotion账号,要记下账号密码后面使用。

注册地址:http://www.genymotion.com/

 

第二步:一般情况下教程上会让先安装VirtualBox,但是根据我的经验,我的建议是先下载安装Genymotion。

下载地址:

https://cloud.genymotion.com/page/customer/login/?next=/page/launchpad/download/

注意想要下载必须先登录。

下载好之后就可以安装了,与普通软件安装过程没有太大的区别,安装目录随意,下一步下一步就OK。

 

安装好Genymotion之后要安装Microsoft Visual C++ 2008 Redistributable Package,所以建议各位看官们,最好也把Microsoft Visual C++ 2010 Redistributable Package以及.net 4.0环境也一并安装了,以免夜长梦多并减少后面的报错(已经安装过的可以自行忽略本步骤)

下载地址1:Microsoft Visual C++ 2008 Redistributable Package

X64:https://www.microsoft.com/zh-cn/download/details.aspx?id=15336

X86:https://www.microsoft.com/zh-cn/download/details.aspx?id=29

下载地址2:Microsoft Visual C++ 2010 Redistributable Package

X64:https://www.microsoft.com/zh-cn/download/details.aspx?id=14632

X86:https://www.microsoft.com/zh-cn/download/details.aspx?id=5555

下载地址3:Microsoft.NET Framework 4(独立安装程序)

https://www.microsoft.com/zh-cn/download/details.aspx?id=17718.

 

第三步:安装好Genymotion之后,下载安装Oracle的VirtulBox,(Genymotion需要虚拟环境才能运行)

下载地址:https://www.virtualbox.org/wiki/Downloads

根据你的实际情况自行选择。下载之后安装,安装过程也没有什么不同,下一步下一步就OK了。这里特别注意的是VirtulBox的安装路径,要是不 对,那么Genymotion就没法打开,现在你打开C:\Users\Administrator\AppData\Local\Genymobile 路径下的genymotion.log文件,文件中比较乱,你找到VBoxManage path (found by reg.exe)这句话,他后面的路径就是你需要安装VirtulBox的路径,这点是非常重要的,切记

 

第四步:启动Gentmoyion,进行一些相关的配置

第一次使用会问你是否添加一个新的虚拟机,选择yes.

进入如上界面,此时便填上你注册Genymoyion账户时的账号和密码,然后点击connect。

连接上之后他会出现设备列表,你可以大致浏览下,然后选择你想创建的一个,点击右下角的add。

然后他会列出一些设备的参数,你大致浏览下,然后点击next。

此时便会开始下载模拟器了。不支持断点续传,所以过程中不要断网,整个过程还是挺快的。

下载完毕后就可以创建了,点击右下角的create。

在这个界面就可以看到你所创建的模拟器的列表,在这个界面play是打开一个模拟器,add是创建一个模拟器,setting自然就是能对模拟器进 行一些设置。这里一步需要特别注意;这个步骤是为模拟器配置SDK,只有配置过的模拟器才能正常的运行程序。选择一个模拟器,点击setting。

在出现的setting界面中

勾选第一条,然后浏览sdk的路径,路径名到sdk为止,如果路径正确,下方的提示会打上粉红色的勾,然后点击OK。

然后回到设备列表,选择一个设备,点击play,就可以启动模拟器了。

关于模拟器的使用方法和一些配置可以再自行百度。因为我也不会,我以后也是要靠google哥哥的。哈哈。

Genymotion的安装过程到这就结束了,接下来讲Eclipse中Genymotion查件的配置与使用。

 

首先第一步:安装Eclipse Genymotion插件,我用的是在线安装的方法,

在线安装的地址为:http://plugins.genymotion.com/eclipse

如果没有被墙或者RP还行的话应该没问题。至于插件安装过程就不是这里该讲的东西了,不会的度娘吧。也可以下载离线包安装。

 

第二步:首次使用配置

安装好插件后你会在Eclipse面板中发现Genymotion的按钮,在sdk manager的隔壁,图标是:,点击他,第一次是不能直接使用的,然后他会指引你去配置Genymotion的directory,

出现如下界面。

此时要填的是Genymotion的安装路径,我的路径如上图所示。路径名到Genymotion为止,添加好后apply,然后OK。

 

第三步:使用它运行项目,配置上第二步之后返回Eclipse,再次点击Genymotion的图标,

他就会出现设备列表了,选择一个点击start就OK,此时你就能发现运行的模拟器了。

 

第四步:运行程序

运行程序之前也要进行配置,在你需要运行的工程处右键,Run as —>Run config……

进入运行设置界面。

选择上图所标注的选项,然后Apply,然后点击Run运行项目,这样就能看到你的项目在Genymotion上顺利运行了,当然我希望是顺利运行哈。

附:Genymotion中文官方手册供大家参阅

地址:http://www.app-edu.net/article-60414-1.html

到此,整个过程也结束了,大家终于可以解放自己的手机了。

互联网上“神”太多了,别造了

mikel阅读(1056)

 互联网上“神”的确太多了,动不动就日赚万元,然后是晒收入,晒发货单的

这么明目张胆的造“神” ,这么赚钱真的心安理得吗?

最近莫名其妙的被拉入很多群,里面都是自媒体圈子的人,大家都脸儿熟儿,开始还互相打个招呼,后来就麻木了,心知肚明,被圈了!

真神和假神很难分辨,各个金光四射的在哪谈经论道,说得听上去都有道理,然后实际操作起来都有问题。

结果蒙头转向的在各个神人的圈子间听讲、培训、直播,没怎么着,一天时间过去了!

日子就这么过,当发现正事儿都耽误了,自己口袋里的钱也没了的时候,才恍然大悟,真“神”!

乌烟瘴气的互联网上难辩真伪,只能严于律己不造“神”,保持本心,务实做事,不再给互联网添乱了,就算“绿色环保”了!

[转载]PHP empty()函数说明 - PHP技术 - 源码之家 - 源码学院

mikel阅读(907)

[转载]PHP empty()函数说明 – PHP技术 – 源码之家 – 源码学院.

    从表面上看,很容易误解empty()函数是判断字符串是否为空的函数,其实并不是,我也因此吃了很多亏。
empty()函数是用来测试变量是否已经配置。若变量已存在、非空字符串或者非零,则返回 false 值;反之返回 true值。所以,当字符串的值为0时,也返回true,就是执行empty内部的语句。这就是陷阱。
如: 假设 $value = 0; 则empty($value)=false。

劝告各位,千万注意使用empty()函数。
判断字符串是否为空,可以这么判断: if ($value==””) …
* 格式:bool empty ( mixed var )
* 功能:检查一个变量是否为空
* 返回值:
* 若变量不存在则返回 TRUE
* 若变量存在且其值为””、0、”0″、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回 TURE
* 若变量存在且值不为””、0、”0″、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回 FALSE
* 版本:PHP 3, PHP 4, PHP 5

从表面上看,很容易误解empty()函数是判断字符串是否为空的函数,其实并不是,我也因此吃了很多亏。 empty()函数是用来测试变量是否已经配置。若变量已存在、非空字符串或者非零,则返回 false 值;反之返回 true值。所以,当字符串的值为0时,也返回true,就是执行empty内部的语句。这就是陷阱。如: 假设 $value = 0; 则empty($value)=false。劝告各位,千万注意使用empty()函数。判断字符串是否为空,可以这么判断: if ($value==””) … 格式:bool empty ( mixed var ) 功能:检查一个变量是否为空 返回值:若变量不存在则返回 TRUE 若变量存在且其值为””、0、”0″、NULL、、FALSE、array()、var $var; 以及没有任何属性的对象,则返回 TURE 若变量存在且值不为””、0、”0″、NULL、、FALSE、array()、var $var; 以及没有任何属性的对象,则返回 FALSE 版本:PHP 3, PHP 4, PHP 5

[转载]敏捷个人手机应用:如何使用时中法目标 - 周 金根 - 博客园

mikel阅读(810)

[转载]敏捷个人手机应用:如何使用时中法目标 – 周 金根 – 博客园.

敏捷个人手机应用:如何查看敏捷个人博客中 我们介绍了查看博客,今天我们要继续介绍的是敏捷个人手机应用中时中法的目标管理功能。关于目标,我们在敏捷个人三大体系练习都有涉及,平衡个人练习帮助 我们在生活中发现目标,高效个人帮助我们去实现目标,快乐个人帮助我们去持续拥有目标,在这里我需要重点重申的是,工具在目标管理来说是次要的,对目标的 认识和追求才是至关重要的。

下面我说一下如何使用时中法目标功能,以便大家可以更为顺利的使用这个工具。

  1. 打开手机应用,登录后切换到【时中】功能,点击最上面的【目标】按钮后,会进入目标管理页面
  2. 这个时候你没有任何目标,你现在可以点击【添加目标】开始加入你的目标
  3. 在手机应用中有两类目标,一类是系统或他人共享的公开目标,你可以和他一起进行,但是你只是一个参与者,你不能更改他人目标下的任务。还有一类是你自己个人的目标,你有权限进行任务维护。下面我们先从公开目标开始,点击上图中的<全家旅游>目标后可以查看这个目标下的任务组成
  4. 如果觉得这也是你想要的目标,那么点击上图的【返回】按钮,回到目标列表页面后,点击【我要实现它】按钮便可以把公开目标添加为你自己的目标了
  5. 添加后可以看到你的目标列表已经有了这个目标了
  6. 这时目标的任务会自动进入时中的【执行】页签中。点击【执行】按钮,进入执行页面,可以看到【未设定开始时间的目标任务】中有刚才加入目标的所有任务
  7. 现在,你可以进行任务的时间计划了。长按任务后弹出任务编辑窗口,例如我在上图的<研究并确定一个目的地>任务上长按之后,弹出任务编辑页面。如果你对时间不太好把握,先不做时间计划也行,可以放到周计划中去进行。
  8. 如果上面计划完成后,你可以开始去执行你的目标任务了。在【执行】页面中,找到你做完的任务,向右滑动,则可以标记完成。例如我们在【列一个目的地列表】任务上向右滑动,则会弹出一个文字列表框,我们可以在这里输入任务备注。
  9. 提交后就可以看到这个任务被标记完成了
  10. 如果你想了解目标的执行进度,可以点击【目标】切换回目标页面,目标下的进度条显示的是完成的任务进度(目前进度只是按照任务数的比例来计算)
  11. 你点击目标后,可以看到任务列表中也会标记完成。为了让你关注你还没做的,已经完成的任务会自动排列到任务最后
  12. 上面是添加公开目标的过程。现在我们来添加一个属于你自己的目标。例如我要为敏捷个人手机应用设定了一个目标,于是点击添加目标后,在添加目标页面最上面的文本框中输入<敏捷个人手机应用>作为目标标题,点击【添加】后弹出目标编辑页面
  13. 在目标编辑页面中,我们要做几项工作,这些工作必须认真思考后填写,否则制定的目标也没有多大意义。

    首先,选择目标所属的生活维度。应用中列出的敏捷个人生活方向盘的8个维度

    然后,根据心流模型,如果我们的目标是有一定挑战而且努力就能达到的是最合适的,在这里选择你的挑战难度

    接着,问问自己,这是你不得不做,还是应该做的,或是想做的、真正想做的

    最后,问问自己为什么要设定这个目标,好好思考并写下来

    以上都完成后,才算得上一次目标制定完成,点击【保存】添加后可以看到目标中已经有了自己的目标了(下面的进度条是我执行后的显示,刚添加是现实的是0%)
  14. 自己的目标制定完成后,必须再做的一步就是目标的任务拆解了。在上图中点击目标进入目标任务页面
  15. 点击【添加任务】进行任务编辑

    这 里需要提一下的是完成状态,这个选择会影响在【执行】中滑动标记时的方式。上面步骤说明中的【列一个目的地列表】任务是字符串列表,所以标记时弹出的是一 个列表文本框。如果你只是想打钩标记,那么选择直接完成。如果你还希望完成时输入数字,则选择完成数量。如果你希望给自己打星,则可以选择完成满意度。建 议大家先都选择直接完成,这样可以有种标记完成的快感
    J
  16. 如果任务添加完后,想要更新的话,那就在任务列表中长按进入编辑页面
  17. 如果想删除任务,则滑动任务来删除即可

目标工具虽重要,但对目标的认识是第一步,欢迎加入敏捷个人 http://www.zhoujingen.cn

[转载]移动互联网实战--社交游戏的排行榜设计和实现(1) - mumuxinfei - 博客园

mikel阅读(895)

[转载]移动互联网实战–社交游戏的排行榜设计和实现(1) – mumuxinfei – 博客园.

前言:
游戏领域, 特别是移动端的社交类游戏, 排行榜成为了一种增强体验交互, 提高用户粘性的大法宝. 这边讲述在不同用户规模下, 游戏服务化/游戏平台化趋势下, 如何去设计和实现游戏排名榜. 本文侧重于传统关系型MySQL的方案实现, 后续会讲解NoSQL的作用. 小编(mumuxinfei)对这块认识较浅, 所述观点不代表主流(工业界)做法, 望能抛砖引玉.

需求分析
曾几何时, 微信版飞机大战红极一时. 各路英雄刷排名, 晒成绩. 不过该排名限制在自己的好友圈中, 而每个用户的好友圈各不一样, 因此每个用户有自己的排名. 且排名按周重置清零. 一些简单的移动端游戏(比如2048, 没有好友概念), 则采用简单的全局排名的方式, 且排名采用历史最高.


综上的列子, 对于游戏排行榜, 我们可以依据属性来进行划分.
1). 按是否属于好友圈划分
* 游戏全局的Top N模式.
* 以自身好友圈为界的Top N模式.
2). 按时间周期来划分
* 按时间周期重置, 比如按周清零
* 历史最高, 没有重置清零机制

基础篇: 
社交类游戏, 在小规模用户的前提下, 借助关系型数据库(mysql)来实现, 采用单库单表.
定义好友表tb_friend

1
2
3
4
5
6
CREATE TABLE IF NOT EXISTS tb_friend (
  id INT PRIMARY KEY AUTO_INCREMENT,
  user_id varchar(64),
  friend_id varchar(64),
  UNIQUE KEY `idx_tb_friend_user_id_friend_id` (`user_id`, `friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

用户得分表tb_score

1
2
3
4
5
6
CREATE TABLE IF NOT EXISTS tb_score (
  id INT PRIMARY KEY AUTO_INCREMENT,
  user_id varchar(64),
  score int,
  UNIQUE KEY `idx_tb_score_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

评注: tb_friend表中user_id/friend_id构成复合索引, 用于维护user_id的好友列表, tb_score用于记录每个用户的得分情况
在该两张表的前提之下, 如何获取该好友的排行榜呢?
利用两表join来实现:

1
2
3
4
SELECT tf.friend_id AS friend_id, ts.score AS score
FROM tb_friend tf JOIN tb_score ts ON tf.friend_id = ts.user_id
WHERE tf.user_id = ?
ORDER BY ts.score DESC

类似的结果如下:

评注: 在sql的join中, 需要注意left join/equal join/right join的区别. 这边选用等值join.

性能评估和执行分析:
1). 小表+大表模式: 在tb_friend单表9801条(100个小伙伴, 互为好友)/tb_score单表53条(53个小伙伴有得分)记录下, 进行join分析
执行规划

1
2
3
4
5
EXPLAIN
SELECT tf.friend_id AS friend_id, ts.score AS score
FROM tb_friend tf JOIN tb_score ts ON tf.friend_id = ts.user_id
WHERE tf.user_id = ?
ORDER BY ts.score DESC

评注: 这边sql优化器非常的智能, 借助了小表驱动大表的join优化方式(小表tb_score驱动大表tb_friend进行join), 小表用到了file sort(总共53行记录), 大表用了index(等值join对应一行大表记录).
2). 等表模式: 在tb_friend单表19602条/tb_score单表5092条记录下, 进行join分析

评注: 这边tb_friend表驱动tb_score作join, tb_friend借助复合索引(user_id,friend_id)来加速优化. Mysql的sql优化器还是相当的智能和强大.

进阶篇:
随着数据规模越来越大, 并发访问量的增加, mysql的访问逐渐变成瓶颈. 同时该join的sql语句涉及的filesort非常耗CPU的. 如何破解这种状况?
*) 引入分布式mysql集群, 进行分库分表.
分库分表作为互联网的一大神器, 作用立竿见影. 但是有所得,就会有所失, 分库分表后, 会失去很多特性. 比如事务性, 外键约束关联. 在业务这层, 会导致涉及用户的tb_score, tb_friend表数据不在同一库中, 进而导致join失效. 最终导致, 在应用层做merge, 使得排名操作演变成 1+N sql操作(1 sql 用于获取好友列表, N sql 用于获取每个好友的得分). 这需要注意.

1+N的SQL演化, 应用层做得分排序, 性能会演变成一场灾难.

1
2
3
4
5
6
(1) 获取用户好友列表
SELECT friend_id FROM tb_friend_{N} WHERE user_id = ?
(2) 遍历获取每个好友的得分
foreach friend_id in friend_list(?)
SELECT score FROM tb_score_{M} WEHRE user_id = ?
(3) 应用层做得分排序

评注: {N},{M}是指具体的分表数, 当然在同一库同一表, 可以借助SELECT * IN (…)来优化,这个得看具体的数据分布. 不过是种很好的思路.
小编观点: 由于tb_friend是大表, 而tb_score是小表, 因此tb_friend采用分库分表(以user_id作为依据)的方式去实现, 而tb_score采用单库单表(便于批量查询)的方式实现. 
当然在工业界, Mysql的优化方案非常的成熟, 不光是分库分表,还有主从分离(Master/Slave机制, Master用于写服务, 多Slave节点提供读服务).
可以参见如下的图示:

总结&后续:
这边主要讲述基于传统关系型数据库mysql来实现基于好友的游戏排行榜, 个人的战绩需要实时的去获取, 而好友列表的战绩能允许有一定的延迟. 而好友战绩的排序实现,就成为了本文的中心议题. Mysql的实现方案在数据量/并发数增加的前提下,还是显示了一定的疲态. 下文将讲解, 如何引入Nosql系统, 在游戏rank中,扮演重要的角色. 期待你的关注.

互联网礼节

mikel阅读(1062)

标题写得有点儿正式,不过确实互联网需要礼节!

别人分享了篇干货,你从中受益受到启发,理应点个赞、推荐或者收藏评论表示感谢。互联网的风气 都是从这点滴的小事儿形成的,和现实中一样要讲究礼节。

为什么大早起的,就写这么正式的日志,是因为早起看了我的LOFTER(http://saveas8.lofter.com/)的博客有30多人点了喜欢或者推荐,还有评论的,我很感谢这些素未蒙面的朋友的,于是认真的对他们一一进行加了关注,并对好的博客内容点了赞和推荐,好内容就应该得到尊重,这样才会形成良性的互联网内容生态圈。
总结几点:

1.文章转载的礼节,理应对原创作者的尊重,好的原创文章每天都有很多出来,我喜欢转载这些文章到,出于尊重都会在转载的第一行写上【转载】xxxx 并加上原文章的链接地址,以示尊重。

2.QQ礼节,很多人遇到问题,就是直接去问人家,好像别人是他雇佣的私人顾问 ,该他几百万似的!自己不懂得动脑子,先百度一下问题看看有没有合适的回答,上来就问,不懂基本的礼貌,求教就要有个求教的样子,整得跟要债的似的!

3.文章摘录的礼节,可能有些时候大家自己文章中要引用一些别人写的很好的东西,建议写清引用的是谁的内容,以示对作者的尊重,你用了人家的东西理应写清东西是人家的,不要拿来就成了自己的,那是盗!

4.程序开发中的礼节,互联网上很多开源的程序很多,有些遵从开源协议,开源协议有很多种比如GPL、LGPL等等具体想了解的可以参考百科(http://baike.baidu.com/view/1373538.htm?fr=aladdin),你用了人家的代码就要遵从人家开源的协议,可以用于商业的,必须署名的等等要求,这样才能让开源更规范。

写了这么多,一时感想,想要改变互联网,先改变自己,从自己做起吧!感谢各位浏览!