Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!


关于2048,我看到很多大神,比如医生,郭神,所以我也研究了一段时间,还好是研究了一套逻辑,这是一整套的2048游戏从设计到逻辑再到编写的全部过程,小伙伴们看仔细咯,刚好今天是礼拜天,一天应该了一把这篇博客发表了,其实2048开发起来还是有点难度的,并且他的逻辑挺强的,我也是看了很多的资料偷学的,很适合来锻炼自己的逻辑性

我们首先先来选择开发环境,这里我们就以Eclipse为IDE,新建一个工程——Game2048

一.Score分数

既然是2048游戏,我们也就做一个简单的,他有一个分数,然后就是一个游戏的布局,我们也做一个简单的4*4的游戏,大概的设计图就是这样

二.游戏类:GameView

因为我们的游戏所使用到的布局就是GridLayout,所以我们新建一个GameView继承自GridLayout,然后通过算法动态添加方块,并且监听手势进行操作,这个重写的GridLayout就是游戏的布局了

<com.lgl.game2048.GameView
        android:id="@+id/game_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

三.实现交互逻辑

我们这里铁定是手势操作啦,这里我们就得区分手势是往上,往下,往左,往右,的手势,这时候,我们就需要用到手势监听——OnTouchListener了,也为了确保是实时监听,我们直接在initView的初始方法中处理

我们其实只要知道两点,用户手指按下的坐标点和手指离开的坐标点,然后进行比对,就能识别出用户的意图了

其实关于MotionEvent的几个方法,大家估计都见怪不怪了,因为用的太多了
// 初始化
    private void initView() {
        // 识别手势
        setOnTouchListener(new OnTouchListener() {

            // 起始点和偏移点
            private float startX, startY, offsetX, offsetY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                /**
                 * 交互逻辑 :我们其实只要知道两点,用户手指按下的坐标点和手指离开的坐标点,然后进行比对,就能识别出用户的意图了
                 */
                switch (event.getAction()) {
                // 手指按下
                case MotionEvent.ACTION_DOWN:
                    // 记录按下的x,y坐标
                    startX = event.getX();
                    startY = event.getY();

                    break;
                // 手指离开
                case MotionEvent.ACTION_UP:
                    // 手指离开之后计算偏移量(离开的位置-按下的位置在进行判断是往哪个方向移动)
                    offsetX = event.getX() - startX;
                    offsetY = event.getY() - startY;

                    // 开始识别方向
                    // offsetX 的绝对值大于offsetY的绝对值 说明在水平方向
                    if (Math.abs(offsetX) > Math.abs(offsetY)) {
                        // (直接<0 会有些许误差,我们可以 <-5)
                        if (offsetX < -5) {
                            // 左
                            System.out.println("左");
                        } else if (offsetX > 5) {
                            // 右
                            System.out.println("右");
                        }
                        // 开始计算垂直方向上下的滑动
                    } else {
                        if (offsetY < -5) {
                            // 上
                            System.out.println("上");
                        } else if (offsetY > 5) {
                            // 下
                            System.out.println("下");
                        }
                    }
                    break;
                }
                return true;
            }
        });
    }
上面的逻辑是不是非常的简单,然后我们操作一下,看log

现在手势识别也是很精准了,当然,我们的代码设计也不能太过臃肿,所以,我们的操作逻辑就不在里面编写了,我们分别实现四个方向的方法

    // 左
    private void isLeft() {

    }

    // 右
    private void isRight() {

    }

    // 上
    private void isTop() {

    }

    // 下
    private void isButtom() {

    }
然后把输出语句替换掉,监听到哪个方向就执行哪个方法
//System.out.println("上,下,左,右");
 private void isXXX() {

    }

四.实现方块类CardView

我们可以把这一个个卡片看作是一个对象,我们每次操作,他都要进行实例化
首先,我们新建一个类CardView继承自FrameLayout,再里面我们要考虑三点

1.卡片

2.卡片上的数字

卡片相同的比较

package com.lgl.game2048;

import android.content.Context;
import android.widget.FrameLayout;
import android.widget.TextView;

public class CardView extends FrameLayout {

    // 卡片数量
    private int num = 0;
    // 卡片文字
    private TextView tv_num;

    public CardView(Context context) {
        super(context);
        // 初始化TextView
        tv_num = new TextView(getContext());
        // 卡片文字大小
        tv_num.setTextSize(20);
        // 布局控制器,填充满整个父容器
        LayoutParams lp = new LayoutParams(-1, -1);
        addView(tv_num, lp);

        setNum(0);
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;

        // 要呈现出来的文字(这里要注意是String类型的)
        tv_num.setText(num + "");
    }

    // 两卡片相同的比较方法
    public boolean equals(CardView card) {

        return getNum() == card.getNum();
    }

}

五.动态分配方块的宽高以及添加方块

1.动态分配方块的宽高

写到这里,就有一个梗了,还是Android的老毛病,屏幕的适配问题,所以我们队卡牌的宽高是不能做限定的,也就是说我们要去根据手机屏幕动态分配卡片的width和height,在这里我们就得用到我之前一篇博客

Android绘图机制(一)——自定义View的基础属性和方法

中提到的一个方法了

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
    }

他负责我们的View在父容器的位置,所以我们动态分配高宽也是在他这里面完成,首先,位置发生改变之后,我们得到的位置是一个确定数,但是为了防止用户是横放这手机,这就蛋疼了,所以我们得进行一个设置了

我们打开AndroidManifest.xml的activity标签中加入

//禁止屏幕横屏
android:screenOrientation="portrait"    

好的,现在可以计算了

宽高求最小值 因为考虑到,我们的方阵他是正方形的,而手机屏幕是长方形的,这样,我们的正方形要设置变长就得求长方形的宽,也就是最小值了

并且我们也不需要他填满宽度,我们需要一点空隙,所以我们减去10个像素

再让他除以4,通过这种方式,我们就可以动态平分这个宽度了
int cardWidth = (Math.min(w, h)-10)/4;

2.添加方块

-1.添加卡片

    // 添加卡片,参数为卡片的宽高,因为他是正方形,所以宽高都是cardWidth
    private void addCard(int cardWidth, int cardHeight) {
        // 创建方块
        CardView c;
        // 循环添加
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                c = new CardView(getContext());
                // num为随机数
                c.setNum(2);
                addView(c, cardWidth, cardHeight);
            }
        }
    }
好的,我们来运行一下(换个AS2.0的模拟器感觉萌萌哒)

-2.方块换行

你会发现,并没有4*4,而且一排没有换行,我们回到GameView的initView()方法中添加
//换行
setColumnCount(4);
现在再看看

-3.文字居中

现在我们调整一下,让文字居中,在CardView中
    //文字居中
    tv_num.setGravity(Gravity.CENTER);

现在是不是好看多了

-4.方块颜色

既然是玩2048我们怎么能少了颜色尼,我们就根据这

Android高效率编码-细节,控件,架包,功能,工具,开源汇总



中的色彩表来,自己觉得什么颜色好看可以自行替换,我们直接来到CardView里面

//设置文字背景(暗卡其色)
tv_num.setBackgroundColor(0xffBDB76A);

-5.方块间距

既然是方块间隔,我们还是回到CardView里面,还记得我们设置的LayoutParams吗?你可能想到了吧,我们用Margins
//设置间距
lp.setMargins(10, 10, 0, 0);

-6.记忆方块

我们所操作之后,会有新生成的卡片,为了不重合,我们得做一个记忆功能
    // 记录卡片的二维数组
     private CardView[][] cards = new CardView[4][4];
然后在addCard()方法中
//记忆
    cards[j][i] = c;

六.随机数

我们先来思考一下这个随机数的逻辑,我们玩2048的时候,是不是开始新游戏的时候会随机出现两个方块,而这两个方块,他是随机出现在4*4的任意位置的,所以,我们确定下来,一开始是两个方块的随机出现,再接下来,我们会发现,他有时候是两个2,但是有时候是一个2,一个4,这个4出现的几率有点小,而且我们作为游戏规则制定者,这个也是我们控制的,这里,我不想他出现的很容易,所以我这里的逻辑就设置成1-9,这样4出现的概率会小很多,好了,基本确定了,我们就开始写代码了,我们写一个方法,在此之前,我们要对之前的代码进行调整一下,在CardView中setNum方法中,我们默认为0就占一格,

// 要呈现出来的文字(这里要注意是String类型的)
        if (num <= 0) {
            tv_num.setText("");
        } else {
            tv_num.setText(num + "");
        }
然后把刚才的文字设置换成0
// c.setNum(2);
   c.setNum(0);
然后我们就可以添加随机数了,我们新建一个方法addRandom();
    // 随机数
    private void addRandom() {
        // 我们新建一个lsit存放空的方块,操作之前清空
        point.clear();
        // 对所有的位置进行遍历
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // 空方块才可以添加数字,有值我们就不添加
                if (cards[j][i].getNum() <= 0) {
                    point.add(new Point(j, i));
                }
            }
        }
        // for循环走完之后我们要取方块
        Point p = point.remove((int) (Math.random() * point.size()));
        // 我们用Math.random()返回一个0-1的数,当大于0.1的时候是2否则就是4,也就是4出现的概率为十分之一
        cards[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4);
    }
这个时候我们就可以开始游戏了,为了方便等下我们需要重新开始游戏,我们就新建一个startGame()方法,让他在onSizeChanged()调用
// 开启游戏
    private void startGame() {
        // 既然是开始游戏,我们就要对所有的值进行清理
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                cards[j][i].setNum(0);
            }
        }
        // 重新添加随机数
        addRandom();
        // 我们要添加两个
        addRandom();
    }
好的,我们现在运行一下啊

这正是我们要的效果,每次进入游戏随机生成两个方块,他会出现在不同的位置,而且会出现2和4,4的概率小很多

七.实现方块滑动,递加逻辑

好的,终于到了核心的东西了,这次我们就要用到之前所写的上下左右方向方法了
// 左
    private void isLeft() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // 往左滑是一行一行去遍历的
                for (int j2 = j + 1; j2 < 4; j2++) {
                    // 如果说遍历到值
                    if (cards[j2][i].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j2][i].getNum());
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);
                            // 让图形继续遍历
                            j--;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j2][i])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }

    // 右
    private void isRight() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int i = 0; i < 4; i++) {
            for (int j = 3; j >= 0; j--) {
                // 往左滑是一行一行去遍历的
                for (int j2 = j - 1; j2 >= 0; j2--) {
                    // 如果说遍历到值
                    if (cards[j2][i].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j2][i].getNum());
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);
                            // 让图形继续遍历
                            j++;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j2][i])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }

    // 上
    private void isTop() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 4; i++) {
                // 往左滑是一行一行去遍历的
                for (int i2 = i + 1; i2 < 4; i2++) {
                    // 如果说遍历到值
                    if (cards[j][i2].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j][i2].getNum());
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);
                            // 让图形继续遍历
                            i--;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j][i2])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }

    // 下
    private void isButtom() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int j = 0; j < 4; j++) {
            for (int i = 3; i >= 0; i--) {
                // 往左滑是一行一行去遍历的
                for (int i2 = i - 1; i2 >= 0; i2--) {
                    // 如果说遍历到值
                    if (cards[j][i2].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j][i2].getNum());
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);
                            // 让图形继续遍历
                            i++;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j][i2])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }
四个方法的逻辑都是大同小异的,不过逻辑性还是很强的,大家可以适当的去研究一下然后我们多增加几个方块先来模拟下效果

八.计分

方块的逻辑差不多写完了,我们先来就在MainActivity里面来实现我们的Score计分

MainActivity

package com.lgl.game2048;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView tv_score;
    //外界可以访问的实例
    private static MainActivity mainActivity = null;
    //积分器
    private int score = 0;

    public MainActivity() {
        mainActivity = this;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv_score = (TextView) findViewById(R.id.tv_score);

    }
    public static MainActivity getMainActivity() {
        return mainActivity;
    }
    public static void setMainActivity(MainActivity mainActivity) {
        MainActivity.mainActivity = mainActivity;
    }

    //清除分数
    public void clearScore(){
        score = 0;
        showScore();
    }
    //分数
    public void showScore(){
        tv_score.setText("分数:"+score);
    }

    public void addScore(int s){
        score += s;
        showScore();
    }
}
这是我们计分的过程,我们思考一下在什么时候计分呢?想想就知道在滑动的时候俩值相加的时候开始计分,所以我们在四个滑动方法有值的判断句中添加
//开始计分                                     MainActivity.getMainActivity().addScore(cards[j][i].getNum());
同时,我们在开始游戏的时候要清零,所以我们在startGame方法中要添加
//计分清零
MainActivity.getMainActivity().clearScore();

九.滑动后增加方块

我们默认进来是两个方块,但是滑动之后我们应该也要随机增加方块才能达到游戏的逻辑,你说是吧!
所以,只要你滑动了,我们就要添加,一直到gameover结束为止,那我们依然在那四个方向方法里写
private void isxx(){
    // 加个判断是否可以添加
    boolean isAdd = false;
    for(....){
        for(....){
            for(....){
                if(....){
                    if(....){
                        ....
                    // 可以添加
                    isAdd = true;
                    }else if(....){
                        ....
                        // 可以添加
                        isAdd = true;
                    }
                }
            }
        }
    }
    // 开始进行判断
        if (isAdd) {
            // 如果可以合并,我们添加随机数
            addRandom();
        }
}
好的,我们现在来运行一下

游戏现在大体上是OK的了

十.游戏结束

游戏有始有终,我们现在就来判断游戏结束,游戏结束有两个前提
1.16个格子都是满的
2.上下左右相邻的格子都不相同
这样的话我们就可以写一个endGame方法,然后让他在每次增加方块的时候调用了

    // 游戏结束
    private void endGame() {
        // 在每次添加新的方块的时候判断一下
        // 是否结束?
        boolean isEnd = true;
        ALL: // 标签,让break跳出整个循环
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // 等于0的话游戏没有结束,或者上下左右还是有相同的数
                if (cards[j][i].getNum() == 0
                // 左
                        || (j > 0 && cards[j][i].equals(cards[j - 1][i]))
                        // 右
                        || (j < 3) && cards[j][i].equals(cards[j + 1][i])
                        // 上
                        || (i > 0 && cards[j][i].equals(cards[j][i - 1]))
                        // 下
                        || (i < 3 && cards[j][i].equals(cards[j][i + 1]))) {
                    // 说明游戏没有结束
                    isEnd = false;
                    break ALL;

                }
            }
        }
        if (isEnd) {
            // 当isEnd = true的时候游戏结束
            new AlertDialog.Builder(getContext())
                    .setTitle("Sorry,游戏结束!")
                    .setMessage("是否重新开始?")
                    .setPositiveButton("是",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    // 重新开始
                                    startGame();
                                }
                            })
                    .setNegativeButton("否",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                }
                            }).show();
        }
    }
好的,现在我们可以来检测一下了

十一.优化之色块

我们的数字每个数字代表一种颜色,这里我就简单的写点颜色,你们要是喜欢可以自己想改什么就改什么
在CardView中setnum方法里
        switch (num) {
        case 0:
            tv_num.setBackgroundColor(0xffBDB76A);
            break;
        case 2:
            tv_num.setBackgroundColor(0xffeee4da);
            break;
        case 4:
            tv_num.setBackgroundColor(0xffede0c8);
            break;
        case 8:
            tv_num.setBackgroundColor(0xfff2b179);
            break;
        case 16:
            tv_num.setBackgroundColor(0xfff59563);
            break;
        case 32:
            tv_num.setBackgroundColor(0xfff67c5f);
            break;
        case 64:
            tv_num.setBackgroundColor(0xfff65e3b);
            break;
        case 128:
            tv_num.setBackgroundColor(0xffedcf72);
            break;
        case 256:
            tv_num.setBackgroundColor(0xffedcc61);
            break;
        case 512:
            tv_num.setBackgroundColor(0xffedc850);
            break;
        case 1024:
            tv_num.setBackgroundColor(0xffedc53f);
            break;
        case 2048:
            tv_num.setBackgroundColor(0xffedc22e);
            break;
        default:
            tv_num.setBackgroundColor(0xff3c3a32);
            break;
        }
我们运行下

Demo下载地址:http://download.csdn.net/detail/qq_26787115/9409068

Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!的更多相关文章

  1. Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程

    Android实训案例(九)--答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程 项目也是偷师的,决心研究一下数据库.所以写的还是很详细的,各位看官,耐着性子看完,实现结果不重要 ...

  2. Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局

    Android实训案例(八)--单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局 阿法狗让围棋突然就被热议了,鸿洋大神也顺势出了篇五子棋单机游戏的视频,我看到了就像膜拜膜拜,就 ...

  3. Android实训案例(五)——四大组件之一ContentProvider的使用,通讯录的实现以及ListView的优化

    Android实训案例(五)--四大组件之一ContentProvider的使用,通讯录的实现 Android四大组件是啥这里就不用多说了,看图吧,他们之间通过intent通讯 我们后续也会一一的为大 ...

  4. Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听

    Android实训案例(六)--四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听 Android中四大组件的使用时重中之重,我这个阶段也不奢望能把他 ...

  5. Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!

    Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...

  6. Android实训案例(二)——Android下的CMD命令之关机重启以及重启recovery

    Android实训案例(二)--Android下的CMD命令之关机重启以及重启recovery Android刚兴起的时候,着实让一些小众软件火了一把,切水果,Tom猫,吹裙子就是其中的代表,当然还有 ...

  7. Android实训案例(一)——计算器的运算逻辑

    Android实训案例(一)--计算器的运算逻辑 应一个朋友的邀请,叫我写一个计算器,开始觉得,就一个计算器嘛,很简单的,但是写着写着发现自己写出来的逻辑真不严谨,于是搜索了一下,看到mk(没有打广告 ...

  8. Android实训案例(七)——四大组件之一Service初步了解,实现通话录音功能,抽调接口

    Service Service的神奇之处,在于他不需要界面,一切的操作都在后台操作,所以很多全局性(手机助手,语音助手)之类的应用很长需要这个,我们今天也来玩玩 我们新建一个工程--ServiceDe ...

  9. Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口

    Service Service的奇妙之处.在于他不须要界面,一切的操作都在后台操作,所以非常多全局性(手机助手,语音助手)之类的应用非常长须要这个.我们今天也来玩玩 我们新建一个project--Se ...

随机推荐

  1. Android Firebase 服务简介

    Firebase初步了解 什么事Firebase?Firebase成立于2011年,在被Google收购之前,Firebase是一个协助开发者快速构建App,能够提供行动应用专用开发平台及SDK的一款 ...

  2. JobTracker,TaskTracker简述

    JobTracker 负责接收用户提交的作业,负责启动.跟踪任务执行.JobSubmissionProtocol是JobClient与JobTracker通信的接口.InterTrackerProto ...

  3. 集合框架之Map接口

    Map是将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值. Map 接口提供三种collection视图,允许以键集.值集或键-值映射关系集的形式查看某个映射的内容.映射顺序定 ...

  4. How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer

    How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer 1 ...

  5. 在Activity,Service,Window中监听Home键和返回键的一些思考,如何把事件传递出来的做法!

    在Activity,Service,Window中监听Home键和返回键的一些思考,如何把事件传递出来的做法! 其实像按键的监听,我相信很多人都很熟练了,我肯定也不会说这些基础的东西,所以,前期,还是 ...

  6. FFmpeg源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  7. C++对象模型的那些事儿之四:拷贝构造函数

    前言 对于一个没有实例化的空类,编译器不会给它默认生成任何函数,当实例化一个空类后,编译器会根据需要生成相应的函数.这类函数包括一下几个: 构造函数 拷贝构造函数 析构函数 赋值运算符 在上一篇博文C ...

  8. 安卓中不同APP之间的消息通信

    昨天在腾讯实习生招聘初试面试时面试官问道我关于两个APP之间相互通信的方式,当时自己回道到了contentProvider与BroadcastReceiver.但他接着问还有没有其它的方式,我跟他说可 ...

  9. [学习笔记]java基础Java8SE开发环境搭建、第一个Java Hello World、Java程序的编译与执行

    本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/25745945 内容简介: ------------ ...

  10. 统计git代码提交量

    以下是我写的一个脚本,可以统计在某个项目中,自己修改代码的行数,包括增加多少行,删除多少行. 可以统计当天,24小时内或全部时间内.使用时需要把代码中的author对应的值换成自己的名字. 代码如下: ...