转载著名出处 : http://blog.csdn.net/shulianghan/article/details/40351487

代码下载 :

-- CSDN 下载地址http://download.csdn.net/detail/han1202012/8069497 ;

-- GitHub 地址https://github.com/han1202012/CircleProcess.git ;

-- 工程示例 :

一. 相关知识点解析

1. 自定义 View 组件构造方法

构造方法 : 自定义的 View 组件, 一般需要实现 三个构造方法, 分别有 一个, 两个, 三个参数;

-- 一个参数public CircleProcess(Context context);

-- 两个参数public CircleProcess(Context context, AttributeSet attrs);

-- 三个参数public CircleProcess(Context context, AttributeSet attrs, int defStyle);

构造方法注意点 :

-- 调用上级方法 : 每个构造方法中必须调用 super() 方法, 方法中的参数与该构造方法参数一样;

-- 常用构造方法 : 一般在2参数构造方法中实现逻辑;

构造方法示例 :

	/** 画笔 */
	private Paint mPaint;
	/** 上下文对象 */
	private Context mContext;
	/** 进度条的值 */
	private int mProcessValue;

	public CircleProcess(Context context, AttributeSet attrs) {
		super(context, attrs);
		// 初始化成员变量 Context
		mContext = context;
		// 创建画笔, 并设置画笔属性
		mPaint = new Paint();
		// 消除绘制时产生的锯齿
		mPaint.setAntiAlias(true);
		// 绘制空心圆形需要设置该样式
		mPaint.setStyle(Style.STROKE);
	}

	/**
	 * 自定义布局实现的 只有 Context 参数的构造方法
	 * @param context
	 */
	public CircleProcess(Context context) {
		super(context);
	}

	/**
	 * 自定义布局实现的 三个参数的构造方法
	 * @param context
	 * @param attrs
	 * @param defStyle
	 */
	public CircleProcess(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

2. dip 和 px 单位转换

(1) dip 转 px

公式 :

-- 基本公式px / dip = dpi / 160;

-- 计算公式 : px = dpi / 160 * dip;

一些概念解析 :

-- dpi 概念 : dpi (dot per inch), 每英寸像素数 归一化的值 120 160 240 320 480;

-- 区分 dpi 和 density : dpi 是归一化的值, density 是实际的值, 可能不是整数;

代码示例 :

	/**
	 * 将手机的 设备独立像素 转为 像素值
	 *
	 * 		公式 : px / dip = dpi / 160
	 * 			   px = dip * dpi / 160;
	 * @param context
	 * 				上下文对象
	 * @param dpValue
	 * 				设备独立像素值
	 * @return
	 * 				转化后的 像素值
	 */
	public static int dip2px(Context context, float dpValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dpValue * scale + 0.5f);
	}

(2) px 转 dip

公式 :

-- 基本公式 : px / dip = dpi / 160;

-- 计算公式 : dip = 160 / dpi * px;

代码 :

	/**
	 * 将手机的 像素值 转为 设备独立像素
	 * 		公式 : px/dip = dpi/160
	 * 			   dip = px * 160 / dpi
	 * 			   dpi (dot per inch) : 每英寸像素数 归一化的值 120 160 240 320 480;
	 * 			   density : 每英寸的像素数, 精准的像素数, 可以用来计算准确的值
	 * 			   从 DisplayMetics 中获取的
	 * @param context
	 * 				上下文对象
	 * @param pxValue
	 * 				像素值
	 * @return
	 * 				转化后的 设备独立像素值
	 */
	public static int px2dip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}

3. 关于 组件 宽 和 高 计算

(1) MesureSpec 简介

: MeasureSpec.UNSPECIFIED, 未指定模式;
-- : MeasureSpec.EXACTLY, 精准模式;
-- : MeasureSpec.AT_MOST, 最大模式;

MeasureSpec 常用方法介绍 :

-- MeasureSpec.getMode(int) : 获取模式;
-- MeasureSpec.getSize(int) : 获取大小;
-- MeasureSpec.makeMeasureSpec(int size, int mode) : 创建一个 MeasureSpec;
-- MeasureSpec.toString(int) : 模式 + 大小 字符串;

(2) 通过 MeasureSpec 计算组件大小

计算方法 :

-- 精准模式 : 该模式下 长度的大小 就是 从 MeasureSpec 中获取的 size 大小;

-- 最大模式 : 获取 默认大小 和 size 中的较小的那个;

-- 未定义模式 : 默认大小;

通用计算方法代码 :

	/**
	 * 获取组件宽度
	 *
	 * MeasureSpec : 该 int 类型有 32 位, 前两位是状态位, 后面 30 位是大小值;
	 * 		常用方法 :
	 * 		-- MeasureSpec.getMode(int) : 获取模式
	 *      -- MeasureSpec.getSize(int) : 获取大小
	 *      -- MeasureSpec.makeMeasureSpec(int size, int mode) : 创建一个 MeasureSpec;
	 *      -- MeasureSpec.toString(int) : 模式 + 大小 字符串
	 *
	 *      模式介绍 : 注意下面的数字是二进制的
	 *      -- 00 : MeasureSpec.UNSPECIFIED, 未指定模式;
	 *      -- 01 : MeasureSpec.EXACTLY, 精准模式;
	 *      -- 11 : MeasureSpec.AT_MOST, 最大模式;
	 *
	 *      注意 : 这个 MeasureSpec 模式是在 onMeasure 方法中自动生成的, 一般不用去创建这个对象
	 *
	 * @param widthMeasureSpec
	 * 				MeasureSpec 数值
	 * @return
	 * 				组件的宽度
	 */
	private int measure(int measureSpec) {
		//返回的结果, 即组件宽度
		int result = 0;
		//获取组件的宽度模式
		int mode = MeasureSpec.getMode(measureSpec);
		//获取组件的宽度大小 单位px
		int size = MeasureSpec.getSize(measureSpec);

		if(mode == MeasureSpec.EXACTLY){//精准模式
			result = size;
		}else{//未定义模式 或者 最大模式
			//注意 200 是默认大小, 在 warp_content 时使用这个值, 如果组件中定义了大小, 就不使用该值
			result = dip2px(mContext, 200);
			if(mode == MeasureSpec.AT_MOST){//最大模式
				//最大模式下获取一个稍小的值
				result = Math.min(result, size);
			}
		}

		return result;
	}

(3) 设置 组件大小方法

setMeasuredDimension() 方法 : 该方法决定 View 组件的大小;

-- 使用场所 : 在 onMeasure() 方法中调用该方法, 就设置了组件的宽 和 高, 然后在其它位置调用 getWidth() 和 getHeight() 方法时, 获取的就是 该方法设置的值;

-- 代码示例 :

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		/*
		 * setMeasuredDimension 方法 : 该方法决定当前的 View 的大小
		 * 根据 View 在布局中的显示, 动态获取 View 的宽高
		 *
		 * 当布局组件 warp_content 时 :
		 * 从 MeasureSpec 获取的宽度 : 492 高度 836 ,
		 * 默认 宽高 都是 120dip转化完毕后 180px
		 *
		 * 当将布局组件 的宽高设置为 240 dp :
		 * 宽度 和 高度 MeasureSpec 获取的都是 360, 此时 MeasureSpec 属于精准模式
		 *
		 */
		setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));
	}

4. 图形绘制

(1) 设置画笔

画笔相关方法 :

-- 消除锯齿 : setAntiAlias(boolean);

		// 消除绘制时产生的锯齿
		mPaint.setAntiAlias(true);

-- 绘制空心圆设置的样式 : setStyle(Style.STROKE);

		// 绘制空心圆形需要设置该样式
		mPaint.setStyle(Style.STROKE);

-- 绘制实心图形文字需要设置的样式 : mPaint.setStrokeWidth(0);

-- 设置画笔颜色 : setColor(Color.BLUE);

-- 设置文字大小 : setTextSize(float);

		//设置数字的大小, 注意要根据 内圆半径设置
		mPaint.setTextSize(innerRadius / 2);

(2) 绘制图形

绘制圆 : canvas.drawCircle(float cx, float cy, float radius, Paint paint);

-- cx 参数 : 圆心的 x 轴距离;

-- cy 参数 : 圆心的 y 轴距离;

-- radius 参数 : 半径;

-- paint : 画笔;

绘制圆弧 :

-- 创建圆弧 : RectF rectf = new RectF(left, top, right, bottom);

-- 绘制 : canvas.drawArc(rectf, 270, mProcessValue, false, mPaint);

-- 示例 :

		//创建圆弧对象
		RectF rectf = new RectF(left, top, right, bottom);
		//绘制圆弧 参数介绍 : 圆弧, 开始度数, 累加度数, 是否闭合圆弧, 画笔
		canvas.drawArc(rectf, 270, mProcessValue, false, mPaint);

绘制文字 : canvas.drawText(str, textX, textY, mPaint);

二. 代码示例

1. 自定义 View 代码

package cn.org.octopus.circle;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.ImageView;

public class CircleProcess extends ImageView {

	/** 画笔 */
	private Paint mPaint;
	/** 上下文对象 */
	private Context mContext;
	/** 进度条的值 */
	private int mProcessValue;

	public CircleProcess(Context context, AttributeSet attrs) {
		super(context, attrs);
		// 初始化成员变量 Context
		mContext = context;
		// 创建画笔, 并设置画笔属性
		mPaint = new Paint();
		// 消除绘制时产生的锯齿
		mPaint.setAntiAlias(true);
		// 绘制空心圆形需要设置该样式
		mPaint.setStyle(Style.STROKE);
	}

	/**
	 * 自定义布局实现的 只有 Context 参数的构造方法
	 * @param context
	 */
	public CircleProcess(Context context) {
		super(context);
	}

	/**
	 * 自定义布局实现的 三个参数的构造方法
	 * @param context
	 * @param attrs
	 * @param defStyle
	 */
	public CircleProcess(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		//获取圆心的 x 轴位置
		int center = getWidth() / 2;
		/*
		 * 中间位置 x 减去左侧位置 的绝对值就是圆半径,
		 * 注意 : 由于 padding 属性存在, |left - right| 可能与 width 不同
		 */
		int outerRadius = Math.abs(getLeft() - center);
		//计算内圆半径大小, 内圆半径 是 外圆半径的一般
		int innerRadius = outerRadius / 2;

		//设置画笔颜色
		mPaint.setColor(Color.BLUE);
		//设置画笔宽度
		mPaint.setStrokeWidth(2);
		//绘制内圆方法 前两个参数是 x, y 轴坐标, 第三个是内圆半径, 第四个参数是 画笔
		canvas.drawCircle(center, center, innerRadius, mPaint);

		/*
		 * 绘制进度条的圆弧
		 *
		 * 绘制图形需要 left top right bottom 坐标, 下面需要计算这个坐标
		 */

		//计算圆弧宽度
		int width = outerRadius - innerRadius;
		//将圆弧的宽度设置给 画笔
		mPaint.setStrokeWidth(width);
		/*
		 * 计算画布绘制圆弧填入的 top left bottom right 值,
		 * 这里注意给的值要在圆弧的一半位置, 绘制的时候参数是从中间开始绘制
		 */
		int top = center - (innerRadius + width/2);
		int left = top;
		int bottom = center + (innerRadius + width/2);
		int right = bottom;

		//创建圆弧对象
		RectF rectf = new RectF(left, top, right, bottom);
		//绘制圆弧 参数介绍 : 圆弧, 开始度数, 累加度数, 是否闭合圆弧, 画笔
		canvas.drawArc(rectf, 270, mProcessValue, false, mPaint);

		//绘制外圆
		mPaint.setStrokeWidth(2);
		canvas.drawCircle(center, center, innerRadius + width, mPaint);

		/*
		 * 在内部正中央绘制一个数字
		 */
		//生成百分比数字
		String str = (int)(mProcessValue * 1.0 / 360 * 100) + "%";
		/*
		 * 测量这个数字的宽 和 高
		 */
		//创建数字的边界对象
		Rect textRect = new Rect();
		//设置数字的大小, 注意要根据 内圆半径设置
		mPaint.setTextSize(innerRadius / 2);
		mPaint.setStrokeWidth(0);
		//获取数字边界
		mPaint.getTextBounds(str, 0, str.length(), textRect);
		int textWidth = textRect.width();
		int textHeight = textRect.height();

		//根据数字大小获取绘制位置, 以便数字能够在正中央绘制出来
		int textX = center - textWidth / 2;
		int textY = center + textHeight / 2;

		//正式开始绘制数字
		canvas.drawText(str, textX, textY, mPaint);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		/*
		 * setMeasuredDimension 方法 : 该方法决定当前的 View 的大小
		 * 根据 View 在布局中的显示, 动态获取 View 的宽高
		 *
		 * 当布局组件 warp_content 时 :
		 * 从 MeasureSpec 获取的宽度 : 492 高度 836 ,
		 * 默认 宽高 都是 120dip转化完毕后 180px
		 *
		 * 当将布局组件 的宽高设置为 240 dp :
		 * 宽度 和 高度 MeasureSpec 获取的都是 360, 此时 MeasureSpec 属于精准模式
		 *
		 */
		setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));
	}

	/**
	 * 获取组件宽度
	 *
	 * MeasureSpec : 该 int 类型有 32 位, 前两位是状态位, 后面 30 位是大小值;
	 * 		常用方法 :
	 * 		-- MeasureSpec.getMode(int) : 获取模式
	 *      -- MeasureSpec.getSize(int) : 获取大小
	 *      -- MeasureSpec.makeMeasureSpec(int size, int mode) : 创建一个 MeasureSpec;
	 *      -- MeasureSpec.toString(int) : 模式 + 大小 字符串
	 *
	 *      模式介绍 : 注意下面的数字是二进制的
	 *      -- 00 : MeasureSpec.UNSPECIFIED, 未指定模式;
	 *      -- 01 : MeasureSpec.EXACTLY, 精准模式;
	 *      -- 11 : MeasureSpec.AT_MOST, 最大模式;
	 *
	 *      注意 : 这个 MeasureSpec 模式是在 onMeasure 方法中自动生成的, 一般不用去创建这个对象
	 *
	 * @param widthMeasureSpec
	 * 				MeasureSpec 数值
	 * @return
	 * 				组件的宽度
	 */
	private int measure(int measureSpec) {
		//返回的结果, 即组件宽度
		int result = 0;
		//获取组件的宽度模式
		int mode = MeasureSpec.getMode(measureSpec);
		//获取组件的宽度大小 单位px
		int size = MeasureSpec.getSize(measureSpec);

		if(mode == MeasureSpec.EXACTLY){//精准模式
			result = size;
		}else{//未定义模式 或者 最大模式
			//注意 200 是默认大小, 在 warp_content 时使用这个值, 如果组件中定义了大小, 就不使用该值
			result = dip2px(mContext, 200);
			if(mode == MeasureSpec.AT_MOST){//最大模式
				//最大模式下获取一个稍小的值
				result = Math.min(result, size);
			}
		}

		return result;
	}

	/**
	 * 将手机的 设备独立像素 转为 像素值
	 *
	 * 		公式 : px / dip = dpi / 160
	 * 			   px = dip * dpi / 160;
	 * @param context
	 * 				上下文对象
	 * @param dpValue
	 * 				设备独立像素值
	 * @return
	 * 				转化后的 像素值
	 */
	public static int dip2px(Context context, float dpValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dpValue * scale + 0.5f);
	}

	/**
	 * 将手机的 像素值 转为 设备独立像素
	 * 		公式 : px/dip = dpi/160
	 * 			   dip = px * 160 / dpi
	 * 			   dpi (dot per inch) : 每英寸像素数 归一化的值 120 160 240 320 480;
	 * 			   density : 每英寸的像素数, 精准的像素数, 可以用来计算准确的值
	 * 			   从 DisplayMetics 中获取的
	 * @param context
	 * 				上下文对象
	 * @param pxValue
	 * 				像素值
	 * @return
	 * 				转化后的 设备独立像素值
	 */
	public static int px2dip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}

	/**
	 * 获取当前进度值
	 * @return
	 * 				返回当前进度值
	 */
	public int getmProcessValue() {
		return mProcessValue;
	}

	/**
	 * 为该组件设置进度值
	 * @param mProcessValue
	 * 				设置的进度值参数
	 */
	public void setmProcessValue(int mProcessValue) {
		this.mProcessValue = mProcessValue;
	}

}

2. Activity 代码

package cn.org.octopus.circle;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

public class MainActivity extends Activity {

	private static CircleProcess circle_process;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //加载 Fragment
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }

        new CircleProcessAnimation().execute();
    }

    /**
     * 设置 异步任务, 在这个任务中 设置 圆形进度条的进度值
     * @author octopus
     *
     */
    class CircleProcessAnimation extends AsyncTask<Void, Integer, Void>{

		@Override
		protected Void doInBackground(Void... arg0) {
			for(int i = 1; i <= 360; i ++){
				try {
					//激活圆形进度条显示方法
					publishProgress(i);
					//每隔 50 毫秒更新一次数据
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);

			//为圆形进度条组件设置进度值
			circle_process.setmProcessValue(values[0]);
			//刷新圆形进度条显示
			circle_process.invalidate();
		}

    }

    /**
     * 界面显示的 Fragment
     * @author octopus
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            circle_process = (CircleProcess) rootView.findViewById(R.id.circle_process);
            return rootView;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

3. 布局文件代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="cn.org.octopus.circle.MainActivity$PlaceholderFragment"
    android:gravity="center">

    <cn.org.octopus.circle.CircleProcess
        android:id="@+id/circle_process"
        android:layout_width="300dip"
        android:layout_height="300dip"/>

</RelativeLayout>

代码下载 :

-- CSDN 下载地址 : http://download.csdn.net/detail/han1202012/8069497 ;

-- GitHub 地址 : https://github.com/han1202012/CircleProcess.git ;

-- 工程示例 :

【Android 应用开发】 自定义 圆形进度条 组件的更多相关文章

  1. vue 圆形进度条组件解析

    项目简介 本组件是vue下的圆形进度条动画组件 自由可定制,几乎全部参数均可设置 源码简单清晰 面向人群 急于使用vue圆形进度条动画组件的同学.直接下载文件,拷贝代码即可运行. 喜欢看源码,希望了解 ...

  2. android 自定义圆形进度条

    一.通过动画实现 定义res/anim/loading.xml如下: [html]  view plain copy print ?   <?xml version="1.0" ...

  3. 【Android进度条】三种方式实现自定义圆形进度条ProgressBar

    一.通过动画实现 定义res/anim/loading.xml如下: <?xml version="1.0" encoding="UTF-8"?> ...

  4. Android 三种方式实现自定义圆形进度条ProgressBar

    一.通过动画实现 定义res/anim/loading.xml如下: <?xml version="1.0" encoding="UTF-8"?> ...

  5. Android自定义圆形进度条,完成类似LOFTER效果

    1.http://stackoverflow.com/questions/3760381/rotating-image-animation-list-or-animated-rotate-androi ...

  6. 自定义VIew——漂亮的圆形进度条

    package com.example.firstapp; import java.text.DecimalFormat; import android.annotation.SuppressLint ...

  7. Android 自定义 View 圆形进度条总结

    Android 自定义圆形进度条总结 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 微信公众号:牙锅子 源码:CircleProgress 文中如有纰漏,欢迎大家留言指出. 最近 ...

  8. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

      Android 高手进阶(21)  版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明地址:http://blog.csdn.net/xiaanming/article/detail ...

  9. android 自定义图片圆形进度条

    感觉话一个圆形进度条挺简单的 ,但是却偏偏给了几张图片让你话,说实话我没接触过,感觉好难,还好百度有大把的资源,一番努力下终于画出来了. 代码如下. package com.etong.cpms.wi ...

随机推荐

  1. drools 手动创建kmoudle.xml文件

    @Test public void test() { KieServices kieServices = KieServices.Factory.get(); KieResources resourc ...

  2. sublime下配置C/C++运行环境

    最近在学习<WEB前端课程>老师教我们使用DW,但是不太喜欢,就选择了sublime,写前端代码还是很方便. 平时都是写C++,C比较多,借鉴了别人的配置步骤,将sublime打造成IDE ...

  3. Java不走弯路教程(1.环境搭建)

    1.环境搭建在开始写第一个Java程序之前,我们需要做一些简单的准备工作. 1.1 还记得DOS吗 我们可以通过图形界面来操作我们的电脑.但作为程序员,你首先需要学会用命令行的方式来操作电脑,因为不是 ...

  4. Python之禅及其翻译

    凡是用过 Python的人,基本上都知道在交互式解释器中输入 import this 就会显示 Tim Peters 的 The Zen of Python,但它那偈语般的语句有点令人费解,所以我想分 ...

  5. ACM Ignatius and the Princess II

    Problem Description Now our hero finds the door to the BEelzebub feng5166. He opens the door and fin ...

  6. 安卓高级5 传感器和震动 模仿微信摇一摇Ui效果

    效果图: 所用的Ui就三张图: 案例代码: 结构 MainActivity.java package com.example.myapp; import android.content.Intent; ...

  7. linux内存管理初始化

    内存管理子系统是linux内核最核心最重要的一部分,内核的其他部分都需要在内存管理子系统的基础上运行.而对其初始化是了解整个内存管理子系统的基础.对相关数据结构的初始化是从全局启动例程start_ke ...

  8. Mac上如何完美的转换epub至mobi供kindle观看

    网上有很多书籍资源的格式都是epub(我们不谈及pdf格式了,你懂得-),epub格式是无法直接在kindle上观赏的,除非你越狱kinde后,安装扩展插件 我们可以将epub转换为mobi格式,网上 ...

  9. Linux 高性能服务器编程——socket选项

    socket选项函数 功能:用来读取和设置socket文件描述符属性的方法 函数: #include <sys/scoket.h> int getsockopt ( int sockfd, ...

  10. 我的第一个RootKit,支持XP、Vista、Win7、Win8 RTM 32位

    只有写过一个BootKit,才能比较深刻的理解其整个过程与机制,也能加深对Windows系统引导各个过程的熟悉和理解. 我写的这个bootkit,暂时还没想到一个比较好的名字,它 1.  支持xp到w ...