MainActivity如下面:

package cc.cc;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
/**
* Demo描写叙述:
* 仿360在Launcher画面显示内存使用率的浮窗.
* 当然这里仅仅是简单地仿O(∩_∩)O
*
* 思路整理:
* 1 涉及到大小两个浮窗.而且两个浮窗之间有逻辑联系.比方:
* 显示小浮窗时不显示大浮窗.所以利用DriftingWindowManager
* 来管理这两个浮窗
* 2 各用一个类来封装和实现两个浮窗的操作
* 3 以上两个类均继承自Layout
*
* 总的来讲该演示样例还是比較简单的
*
* 学习资料:
* 1 http://blog.csdn.net/guolin_blog/article/details/8689140
* 2 http://blog.csdn.net/feng88724/article/details/6362710
* 3 http://blog.csdn.net/hudashi/article/details/6901118
* 4 http://blog.csdn.net/hudashi/article/details/7060882
* 5 http://blog.csdn.net/hudashi/article/details/7061240
* Thank you very much
*
*/
public class MainActivity extends Activity {
private Context mContext;
private Button mStartButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
} private void init(){
mContext=this;
mStartButton=(Button) findViewById(R.id.button);
mStartButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent();
intent.setAction("dws");
mContext.startService(intent);
finish();
}
});
} }

DriftingBigWindow例如以下:

package cc.cc;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
/**
*大浮窗
*
*大浮窗继承自LinearLayout
*该大浮窗主要实现的功能
*1 关闭大浮窗显示小浮窗
*2 关闭全部浮窗且停止对于内存使用率的监控
*
*注意方法:
*LayoutInflater.inflate(int resource, ViewGroup root)的第二參数
*若设置了root,那么会把新生成的View连接到root,该方法的返回为root.
*否未设置root,则返回的是新生成的View
*/
public class DriftingBigWindow extends LinearLayout {
//整个大浮窗的宽和高
public static int width=0;
public static int height=0;
private Context mContext;
public DriftingBigWindow(Context context) {
super(context);
mContext=context;
LayoutInflater layoutInflater=LayoutInflater.from(mContext);
View bigWindowView=layoutInflater.inflate(R.layout.drifting_window_big, this);
View driftingBigWindowRootView=bigWindowView.findViewById(R.id.driftingBigWindowRootView);
//获取大浮窗整个布局的宽和高
width=driftingBigWindowRootView.getLayoutParams().width;
height=driftingBigWindowRootView.getLayoutParams().height;
//停止服务且移除浮窗
Button closeButton=(Button) bigWindowView.findViewById(R.id.closeButton);
closeButton.setOnClickListener(new ClickListenerImpl());
//显示小浮窗
Button backButton=(Button) bigWindowView.findViewById(R.id.backButton);
backButton.setOnClickListener(new ClickListenerImpl());
} private class ClickListenerImpl implements OnClickListener{
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.closeButton:
Intent intent=new Intent();
intent.setAction("dws");
mContext.stopService(intent);
DriftingWindowManager.removeDriftingSmallWindow(mContext);
DriftingWindowManager.removeDriftingBiglWindow(mContext);
break;
case R.id.backButton:
DriftingWindowManager.showDriftingSmallWindow(mContext);
DriftingWindowManager.removeDriftingBiglWindow(mContext);
break;
default:
break;
} } } }

DriftingSmallWindow例如以下:

package cc.cc;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
*小浮窗
*
*小浮窗继承自LinearLayout
*该小浮窗主要实现的功能:
*1 显示手机的内存使用率
*2 在Home界面被任意移动位置
* 所以重点是实现TouchListener,在Touch监听中
* 不断调用mWindowManager.updateViewLayout()
* 改动小浮窗在屏幕上的LayoutParams
*
*注意方法:
*LayoutInflater.inflate(int resource, ViewGroup root)的第二參数
*若设置了root,那么会把新生成的View连接到root,该方法的返回为root.
*否未设置root,则返回的是新生成的View
*/
public class DriftingSmallWindow extends LinearLayout {
//整个小浮窗的宽和高
public static int width=0;
public static int height=0;
private float XInScreen_Down = 0;
private float YInScreen_Down = 0;
private float XInScreen_Move = 0;
private float YInScreen_Move = 0;
private float XInScreen_Up = 0;
private float YInScreen_Up = 0;
private float XInView_Down=0;
private float YInView_Down=0;
private Context mContext;
private WindowManager mWindowManager;
private static WindowManager.LayoutParams mWindowManagerLayoutParams; public DriftingSmallWindow(Context context) {
super(context);
mContext=context;
mWindowManager=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
LayoutInflater layoutInflater = LayoutInflater.from(context);
View smallWindowView=layoutInflater.inflate(R.layout.drifting_window_small, this);
View driftingSmallWindowRootView=smallWindowView.findViewById(R.id.driftingSmallWindowRootView);
TextView percentTextView=(TextView) smallWindowView.findViewById(R.id.percentTextView);
//获取小浮窗整个布局的宽和高
width=driftingSmallWindowRootView.getLayoutParams().width;
height=driftingSmallWindowRootView.getLayoutParams().height;
percentTextView.setText(Utils.getAvailMemoryPercent(context)); this.setOnTouchListener(new TouchListenerImpl());
//this.setOnClickListener(new ClickListenerImpl());
} /**
* 利用该方式监听点击事件不靠谱
* 所以在MotionEvent.ACTION_UP中处理点击事件
*/
private class ClickListenerImpl implements OnClickListener{
@Override
public void onClick(View view) { } } /**
* 对于小浮窗Touch事件的监听
* 注意在MotionEvent.ACTION_UP中处理点击事件
*/
private class TouchListenerImpl implements OnTouchListener{
@Override
public boolean onTouch(View view, MotionEvent event) {
int statusBarHeight=Utils.getStatusBarHeight(mContext);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
XInScreen_Down=event.getRawX();
YInScreen_Down=event.getRawY()-statusBarHeight;
XInView_Down=event.getX();
YInView_Down=event.getY();
break;
case MotionEvent.ACTION_MOVE:
XInScreen_Move=event.getRawX();
YInScreen_Move=event.getRawY()-statusBarHeight; updateWindowManagerLayoutParams(); break;
case MotionEvent.ACTION_UP:
XInScreen_Up=event.getRawX();
YInScreen_Up=event.getRawY()-statusBarHeight;
if (XInScreen_Down==XInScreen_Up&&YInScreen_Down==YInScreen_Up) {
showDriftingBigWindow();
}
break; default:
break;
} return true;
} }; /**
* 保存小浮窗在Window中的布局參数
*/
public static void saveWindowManagerLayoutParams(WindowManager.LayoutParams layoutParams){
mWindowManagerLayoutParams=layoutParams;
} /**
* 更新小浮窗在Window中的布局參数
*
* 注意事项:
* X(Y)InScreen_Move表示触摸点离屏幕左上角的距离
* X(Y)InView_Down表示触摸点离DriftingSmallWindow(小浮窗)自身左上角的距离.
* 两者相减即得DriftingSmallWindow(小浮窗)左上角的坐标
*/
private void updateWindowManagerLayoutParams(){
mWindowManagerLayoutParams.x=(int) (XInScreen_Move-XInView_Down);
mWindowManagerLayoutParams.y=(int) (YInScreen_Move-YInView_Down);
mWindowManager.updateViewLayout(this, mWindowManagerLayoutParams);
} /**
* 显示大浮窗且关闭小浮窗
*/
private void showDriftingBigWindow(){
DriftingWindowManager.showDriftingBiglWindow(mContext);
DriftingWindowManager.removeDriftingSmallWindow(mContext);
} }

DriftingWindowManager例如以下:

package cc.cc;

import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.TextView; /**
* 管理大小浮动窗体
* 在该应用中主要包括了大小两个浮动窗体及其相应的操作
* 比方显示,更新和移除等,所以就写了个DriftingWindowManager
* 来实施这些操作.
* 至于大小浮窗各自要做的操作则是在DriftingSmallWindow和DriftingBigWindow
* 各个类中详细实施的.
* 这个和平时其它的代码原理是一样的:
* 比方在一个类A中使用了(相似于此处的浮窗显示,更新,移除)B和C的对象.
* 但B和C对象的方法是在各自的类中实现的.
*/
public class DriftingWindowManager {
private static WindowManager mWindowManager=null;
private static DriftingSmallWindow mDriftingSmallWindow=null;
private static DriftingBigWindow mDriftingBigWindow=null;
//注意该LayoutParams属于android.view.WindowManager.LayoutParams
private static LayoutParams mDriftingSmallWindowLayoutParams;
private static LayoutParams mDriftingBigWindowLayoutParams; /**
* 显示小浮窗
* 显示位置为屏幕中间右对齐
*/
public static void showDriftingSmallWindow(Context context) {
WindowManager windowManager = getWindowManager(context);
int screenWidth = windowManager.getDefaultDisplay().getWidth();
int screenHeight = windowManager.getDefaultDisplay().getHeight();
//new了一个DriftingSmallWindow对象,在后面会用WindowManager将
//其加入到屏幕中
mDriftingSmallWindow = new DriftingSmallWindow(context);
if (mDriftingSmallWindowLayoutParams == null) {
mDriftingSmallWindowLayoutParams = new LayoutParams();
mDriftingSmallWindowLayoutParams.type = LayoutParams.TYPE_PHONE;
mDriftingSmallWindowLayoutParams.format = PixelFormat.RGBA_8888;
mDriftingSmallWindowLayoutParams.flags =
LayoutParams.FLAG_NOT_TOUCH_MODAL| LayoutParams.FLAG_NOT_FOCUSABLE;
mDriftingSmallWindowLayoutParams.gravity = Gravity.LEFT| Gravity.TOP;
mDriftingSmallWindowLayoutParams.width = DriftingSmallWindow.width;
mDriftingSmallWindowLayoutParams.height = DriftingSmallWindow.height;
//使小浮窗在屏幕上垂直居中,水平靠右的位置显示
mDriftingSmallWindowLayoutParams.x = screenWidth-DriftingSmallWindow.width;
mDriftingSmallWindowLayoutParams.y = screenHeight / 2;
System.out.println("DriftingSmallWindow.width="+DriftingSmallWindow.width);
System.out.println("mDriftingSmallWindowLayoutParams.x="+mDriftingSmallWindowLayoutParams.x);
System.out.println("mDriftingSmallWindowLayoutParams.y="+mDriftingSmallWindowLayoutParams.y);
}
//当显示小浮窗的时保存小浮窗的LayoutParams至该DriftingSmallWindow对象
//由于每次移动小浮窗的时候须要改动该LayoutParams的參数值X和Y
mDriftingSmallWindow.saveWindowManagerLayoutParams(mDriftingSmallWindowLayoutParams);
mWindowManager.addView(mDriftingSmallWindow,mDriftingSmallWindowLayoutParams);
} /**
* 更新小浮窗
*/
public static void updateDriftingSmallWindow(Context context){
if(mDriftingSmallWindow!=null){
TextView percentTextView=(TextView) mDriftingSmallWindow.findViewById(R.id.percentTextView);
percentTextView.setText(Utils.getAvailMemoryPercent(context));
}
} /**
* 移除小浮窗
*/
public static void removeDriftingSmallWindow(Context context){
mWindowManager=getWindowManager(context);
if(mWindowManager!=null&&mDriftingSmallWindow!=null){
mWindowManager.removeView(mDriftingSmallWindow);
mDriftingSmallWindow=null;
}
} /**
* 显示大浮窗
* 显示位置为屏幕中间
*
* 注意细节问题
* 例如以下写法,有偏差,显示效果并不好
* mDriftingBigWindowLayoutParams.x = screenWidth / 2;
* mDriftingBigWindowLayoutParams.y = screenHeight / 2;
* 给人的感觉是大浮窗并没有在屏幕中间位置.
* 由于这个mDriftingBigWindowLayoutParams.x(y)指的是大浮窗
* 在屏幕上显示的x(y)的開始坐标值,即从哪个坐标開始摆放大浮窗.
* 极端地说假设大浮窗就沙子那么大,那么这么做就没有问题,由于大浮窗
* 本身就没有什么宽和高.
* 但在实际中我们还要考虑到控件本身(此处的大浮窗)的长和宽,做到
* 真的居中显示
* 所以应该这么写:
* mDriftingBigWindowLayoutParams.x = screenWidth / 2- DriftingBigWindow.width / 2;
* mDriftingBigWindowLayoutParams.y = screenHeight / 2- DriftingBigWindow.height / 2;
* 相似的问题在小浮窗的拖动过程中也有
*/
public static void showDriftingBiglWindow(Context context) {
WindowManager windowManager = getWindowManager(context);
int screenWidth = windowManager.getDefaultDisplay().getWidth();
int screenHeight = windowManager.getDefaultDisplay().getHeight();
mDriftingBigWindow = new DriftingBigWindow(context);
if (mDriftingBigWindowLayoutParams == null) {
mDriftingBigWindowLayoutParams = new LayoutParams();
mDriftingBigWindowLayoutParams.x = screenWidth / 2- DriftingBigWindow.width / 2;
mDriftingBigWindowLayoutParams.y = screenHeight / 2- DriftingBigWindow.height / 2;
mDriftingBigWindowLayoutParams.type = LayoutParams.TYPE_PHONE;
mDriftingBigWindowLayoutParams.format = PixelFormat.RGBA_8888;
mDriftingBigWindowLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mDriftingBigWindowLayoutParams.width = DriftingBigWindow.width;
mDriftingBigWindowLayoutParams.height = DriftingBigWindow.height;
}
windowManager.addView(mDriftingBigWindow,mDriftingBigWindowLayoutParams);
} /**
* 移除大浮窗
*/
public static void removeDriftingBiglWindow(Context context){
mWindowManager=getWindowManager(context);
if(mWindowManager!=null&&mDriftingBigWindow!=null){
mWindowManager.removeView(mDriftingBigWindow);
mDriftingBigWindow=null;
}
} /**
* 是否有浮窗在Launcher上显示
*/
public static boolean isDriftingWindowShowing(){
if (mDriftingSmallWindow!=null||mDriftingBigWindow!=null) {
return true;
} else {
return false;
}
} /**
* 获取WindowManager
*/
private static WindowManager getWindowManager(Context context){
if (mWindowManager==null) {
mWindowManager=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
return mWindowManager;
} }

DriftingWindowService例如以下:

package cc.cc;

import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
/**
* 利用该服务进行定时任务
*
*/
public class DriftingWindowService extends Service {
private Timer mTimer;
private TimerTask mTimerTask;
private Context mContext;
private Handler mHandler;
@Override
public void onCreate() {
super.onCreate();
} @Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
mContext=this;
mHandler=new Handler();
mTimer=new Timer();
mTimerTask=new TimerTaskSubclass();
//开启定时的任务
mTimer.schedule(mTimerTask, 100, 500);
} @Override
public IBinder onBind(Intent arg0) {
return null;
} @Override
public void onDestroy() {
super.onDestroy();
if (mTimer!=null) {
mTimer.cancel();
}
} private class TimerTaskSubclass extends TimerTask{
@Override
public void run() {
//当前是Launcher,则显示小浮窗
if (Utils.currentIsLauncher(mContext)&&!DriftingWindowManager.isDriftingWindowShowing()) {
mHandler.post(new Runnable() {
@Override
public void run() {
DriftingWindowManager.showDriftingSmallWindow(mContext);
}
});
} //当前不是Launcher且有浮窗显示,则移除浮窗
if(!Utils.currentIsLauncher(mContext)&&DriftingWindowManager.isDriftingWindowShowing()){
mHandler.post(new Runnable() {
@Override
public void run() {
DriftingWindowManager.removeDriftingSmallWindow(mContext);
DriftingWindowManager.removeDriftingBiglWindow(mContext);
}
});
} //当前是Launcher,则更新内存使用率
if(Utils.currentIsLauncher(mContext)){
mHandler.post(new Runnable() {
@Override
public void run() {
DriftingWindowManager.updateDriftingSmallWindow(mContext);
}
});
}
} } }

Utils例如以下:

package cc.cc;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.Context; public class Utils {
/**
* 获取设备状态栏高度
*/
public static int getStatusBarHeight(Context context) {
int statusBarHeight = 0;
try {
Class clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
Field field = clazz.getField("status_bar_height");
// 反射出该对象中status_bar_height字段所相应的在R文件的id值
// 该id值由系统工具自己主动生成,文档描写叙述例如以下:
// The desired resource identifier, as generated by the aapt tool.
int id = Integer.parseInt(field.get(object).toString());
// 根据id值获取到状态栏的高度,单位为像素
statusBarHeight = context.getResources().getDimensionPixelSize(id);
} catch (Exception e) {
}
return statusBarHeight;
} /**
* 推断设备当前是否停留在Launcher
*/
public static boolean currentIsLauncher(Context context){
boolean isLauncher=false;
String topActivityName=getTopActivityName(context);
if (topActivityName!=null&&topActivityName.startsWith("HomeActivity")) {
isLauncher=true;
}
return isLauncher;
} /**
* 获取栈顶Activity名称
*/
public static String getTopActivityName(Context context) {
String topActivityName = null;
ActivityManager activityManager =
(ActivityManager)(context.getSystemService(android.content.Context.ACTIVITY_SERVICE));
List<RunningTaskInfo> runningTaskInfos = activityManager.getRunningTasks(1);
if (runningTaskInfos != null) {
ComponentName f = runningTaskInfos.get(0).topActivity;
String topActivityClassName = f.getClassName();
String temp[] = topActivityClassName.split("\\.");
// 栈顶Activity的名称
topActivityName = temp[temp.length - 1];
}
return topActivityName;
} /**
* 获取当前内存的可用率
*/
public static String getAvailMemoryPercent(Context context){
String info=null;
long availMemory=getAvailMemory(context);
long totalMemory=getTotalMemory();
float percent=(availMemory*100/totalMemory);
info=percent+"%";
return info;
} /**
* 获取内存总大小
*/
public static long getTotalMemory() {
// 系统的内存信息文件
String filePath = "/proc/meminfo";
String lineString;
String[] stringArray;
long totalMemory = 0;
try {
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader,1024 * 8);
// 读取meminfo第一行,获取系统总内存大小
lineString = bufferedReader.readLine();
// 依照空格拆分
stringArray = lineString.split("\\s+");
// 获得系统总内存,单位KB
totalMemory = Integer.valueOf(stringArray[1]).intValue();
bufferedReader.close();
} catch (IOException e) {
}
return totalMemory / 1024;
} /**
* 获取可用内存大小
*/
public static long getAvailMemory(Context context) {
ActivityManager activityManager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
MemoryInfo memoryInfo = new MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
return memoryInfo.availMem / (1024 * 1024);
} }

main.xml例如以下:

<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"
> <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启浮动窗体"
android:layout_centerInParent="true"
/> </RelativeLayout>

drifting_window_big.xml例如以下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/driftingBigWindowRootView"
android:layout_width="130dip"
android:layout_height="130dip"
android:orientation="vertical" > <Button
android:id="@+id/closeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="关闭全部浮窗" /> <Button
android:id="@+id/backButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="返回到小浮窗" /> </LinearLayout>

drifting_window_small.xml例如以下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/driftingSmallWindowRootView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="45dip"
android:layout_height="30dip"
android:background="#00cc00"
android:orientation="horizontal" > <TextView
android:id="@+id/percentTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#ff0000"
android:layout_gravity="center_vertical"
/> </LinearLayout>

AndroidManifest.xml例如以下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.cc"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" /> <!-- 注意权限 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.GET_TASKS"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="cc.cc.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <!-- 注冊服务 -->
<service android:name="cc.cc.DriftingWindowService">
<intent-filter >
<action android:name="dws"/>
</intent-filter>
</service>
</application> </manifest>

版权声明:本文博客原创文章,博客,未经同意,不得转载。

最新文章

  1. VS中C++ 项目重命名
  2. LeetCode 88 Merge Sorted Array
  3. ASCII、Unicode、GBK和UTF-8字符编码的区别联系
  4. 最小生成树之Kruskal算法
  5. 1012 最小公倍数LCM
  6. nginx的rewrite,gzip,反向代理学习笔记
  7. 刀哥多线程之gcd-01-sync&amp;async
  8. rmmod 无法卸载模块问题
  9. apache + tomcat 集群
  10. MVC 读取图片
  11. 【C#基础知识】静态构造函数,来源于一道面试题的理解
  12. (转)Spring的单例模式底层实现
  13. js For循环练习。
  14. js 资料
  15. 使用logstash同步MySQL数据到ES
  16. gear gym 思维题
  17. laravel中常用的获取路径的函数
  18. 关于Unity中的光照(六)
  19. HTML5标签canvas制作平面图
  20. 给WebAPI的REST接口服务添加测试页面(一)

热门文章

  1. 2014辽宁省赛 Repeat Number
  2. CodeForce 356A Knight Tournament(set应用)
  3. 开发测试时给 Kafka 发消息的 UI 发送器――Mikasa
  4. matlab矩阵的表示和简单操作
  5. wpf dll和exe合并成一个新的exe
  6. Anyterm - Introduction
  7. 《C/C++专项练习》 — (3)
  8. 使用yiic安装开发web应用和解决yiic不是内部命令
  9. hdu 4961 Boring Sum(数学题)
  10. Android中Broadcast Receiver组件具体解释