关于Android源码中|= (m & STATIC_VALUE) !=0 的理解

看Android源码时发现有很多地方都用这种方式

private static final int STATIC_CHANGE_1 = 1 << 0 ;
private static final int STATIC_CHANGE_2 = 1 << 1 ;

private static final int STATIC_CHANGE_A = 1 << 2 ;
private static final int STATIC_CHANGE_B = 1 << 3 ;

private static final int STATIC_CHANGE_C = 1 << 4 ;
private static final int STATIC_CHANGE_3 = 1 << 5 ;
private static final int STATIC_CHANGE_4 = 1 << 6 ;


private int mDirty = 0;


如果STATIC_CHANGE_1 代表的变化发生了,就用 mDirty |= STATIC_CHANGE_1 ;

如果要判断STATIC_CHANGE_1 是否发生了,就判断 mDirty & STATIC_CHANGE_1 != 0,为true则发生了。


想想其实这和View测量的数值有点类似,把两个数合成在一起,低两位代表一个值,高位代表另外一个值。


这里的mDirty的二进制每一位相当一个boolean,因为每个static都是*2的,所以不会互相干扰。

比如mDirty = 0 ,先是 |= STATIC_CHANGE_1 就是 0 |= 1 -----》 1

再 |= STATIC_CHANGE_A  (4) --》  1 |= 100  --》 101

这样在判断STATIC_CHANGE_1 和STATIC_CHANGE_A 的时候,都能判断出是否改变过,化成二进制的时候明显可以看到,

对应位置上1就是true,0就是false。



为什么?

先来看看传统做法:

private boolean change1 = false;

private boolean change2 = false;

....................

可以看到声明了很多的私有变量,而且不优雅。


什么情况可以用?

1.状态可以叠加,就是change1并不会覆盖change2

2.没想到,下次补充

以下是一个基于Java的Android扫雷游戏的源码示例,你可以参考一下: ```java public class MainActivity extends AppCompatActivity { private static final int NUM_ROWS = 10; private static final int NUM_COLS = 10; private static final int NUM_MINES = 15; private Button[][] buttons = new Button[NUM_ROWS][NUM_COLS]; private int[][] counts = new int[NUM_ROWS][NUM_COLS]; private boolean[][] revealed = new boolean[NUM_ROWS][NUM_COLS]; private boolean[][] flagged = new boolean[NUM_ROWS][NUM_COLS]; private int numMines = NUM_MINES; private boolean gameOver = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); generateMines(); for (int row = 0; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS; col++) { Button button = new Button(this); button.setLayoutParams(new LinearLayout.LayoutParams(100, 100)); button.setBackgroundResource(R.drawable.button_bg); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (gameOver) { return; } Button button = (Button) v; int row = (int) button.getTag(R.id.row); int col = (int) button.getTag(R.id.col); if (flagged[row][col]) { return; } if (counts[row][col] == -1) { gameOver(); } else { reveal(row, col); checkWin(); } } }); button.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (gameOver) { return true; } Button button = (Button) v; int row = (int) button.getTag(R.id.row); int col = (int) button.getTag(R.id.col); if (!revealed[row][col]) { flagged[row][col] = !flagged[row][col]; updateButton(button, row, col); checkWin(); } return true; } }); LinearLayout rowLayout = findViewById(getResources().getIdentifier("row_" + row, "id", getPackageName())); rowLayout.addView(button); buttons[row][col] = button; button.setTag(R.id.row, row); button.setTag(R.id.col, col); } } } private void generateMines() { Random random = new Random(); for (int i = 0; i < NUM_MINES; i++) { int row, col; do { row = random.nextInt(NUM_ROWS); col = random.nextInt(NUM_COLS); } while (counts[row][col] == -1); counts[row][col] = -1; for (int r = row - 1; r <= row + 1; r++) { for (int c = col - 1; c <= col + 1; c++) { if (r >= 0 && r < NUM_ROWS && c >= 0 && c < NUM_COLS && counts[r][c] != -1) { counts[r][c]++; } } } } } private void reveal(int row, int col) { if (revealed[row][col]) { return; } revealed[row][col] = true; Button button = buttons[row][col]; updateButton(button, row, col); if (counts[row][col] == 0) { for (int r = row - 1; r <= row + 1; r++) { for (int c = col - 1; c <= col + 1; c++) { if (r >= 0 && r < NUM_ROWS && c >= 0 && c < NUM_COLS && (r != row || c != col)) { reveal(r, c); } } } } } private void updateButton(Button button, int row, int col) { if (flagged[row][col]) { button.setText("F"); } else if (revealed[row][col]) { int count = counts[row][col]; if (count == 0) { button.setText(""); } else { button.setText(String.valueOf(count)); } } else { button.setText(""); } } private void gameOver() { gameOver = true; for (int row = 0; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS; col++) { if (counts[row][col] == -1) { revealed[row][col] = true; updateButton(buttons[row][col], row, col); } } } Toast.makeText(this, "Game over!", Toast.LENGTH_SHORT).show(); } private void checkWin() { int numRevealed = 0; for (int row = 0; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS; col++) { if (revealed[row][col]) { numRevealed++; } } } if (numRevealed == NUM_ROWS * NUM_COLS - NUM_MINES) { Toast.makeText(this, "You win!", Toast.LENGTH_SHORT).show(); } } } ``` 这个示例代码使用一个二维数组来表示扫雷游戏的方格,其-1表示地雷,其他数字表示周围地雷的数量。它还使用另外两个二维数组来跟踪哪些方格已经被揭示和哪些方格被标记。在点击和长按方格时,它会根据游戏规则揭示或标记方格,并在必要时检查游戏是否结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值