Android Studio --- > [学习笔记]RadioButton、CheckBox、ImageView、ListView、TCP的三次握手

说明


2.5 RadioButton

  • 常用属性
  • 自定义样式
  • 监听事件

2.5.1 新建按钮,并跳转到相应的活动页面

1.在com.skypan.textview下新建一个RadioButtonActivity活动
2.在主样式,新增一个 RadioButton按钮

<Button
  android:id="@+id/btn_radiobutton"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="Radio Button"
  android:textAllCaps="false"/>

3.在主活动中,添加按钮的跳转事件

public class MainActivity extends AppCompatActivity {
  // 声明按钮
  private Button mBtnRadioButton;

  @override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mBtnRadioButton = (Button) findViewById(R.id.btn_radiobutton);
    mBtnRadioButton.setOnClickListener(new View.OnClickListener(){
      @Override
      public void onClick(View v) {
        // 跳转到 RadioButton 界面
        Intent intent = new Intent(MainActivity.this, RadioButtonActivity.class);
        startActivity(intent);
      }
    })
  }
}

2.5.2 封装View.OnClickListener

[说明] : 在主活动中,多次使用到这个方法,其中仅仅部分改变.因此将该方法提取出来.
1.提取出方法

private class OnClick implements View.OnClickListener{
    @Override
    public void onClick(View v) {
        Intent intent = null;
        switch (v.getId()){
            case R.id.btn_textview:
                // 跳转到 TextView 演示界面
                intent = new Intent(MainActivity.this, TextViewActivity.class);
                break;
            case R.id.btn_button:
                intent = new Intent(MainActivity.this, ButtonActivity.class);
                break;
            case R.id.btn_edittext:
                intent = new Intent(MainActivity.this, EditTextActivity.class);
                break;
            case R.id.btn_radiobutton:
                intent = new Intent(MainActivity.this, RadioButtonActivity.class);
                break;
        }
        startActivity(intent);
    }
}

2.设置启动函数

private void setListeners(){
  Onclick onclick = new Onclick();
  mBtnTextView.setOnClickListener(onClick);
  mBtnButton.setOnClickListener(onClick);
  mBtnEditText.setOnClickListener(onClick);
  mBtnRadioButton.setOnClickListener(onClick);
}

2.5.3 单选按钮的监听事件:

  • 按钮组的布局如下:
<RadioGroup
  android:id="@+id/rg_1"
  ...
/>
  <RadioButton
    android:id="@+id/rb_1"
    android:text=""
  />
  <RadioButton
    android:id="@+id/rb_2"
    android:id=""
  />
</RadioGroup>
  • 监听函数如下:
public class RadioButtonActivity extends AppCompatActivity {
  private RadioGroup mRg1;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mRg1 = (RadioGroup) findViewById(R.id.rg_1);
    mRg1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged(RadioGroup group, int checkedId) {
        RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
        Toast.makeText(RadioButtonActivity.this, radioButton.getText(),Toast.LENGTH.SHORT).show();
      }
    })
  }
}

[说明] :
1.一个活动对应的是一个类
2.所有活动都继承一个基类AppCompatActiviry
3.protected: 自己和子类都能使用.
4.private: 除了自己之外,其他类都无法使用

2.5.x 参数说明:

1.android:checked: 默认选中
2.android:state_checked="true": 点击时显示的样式
3.<solid android:color="#cc7a00">: 一个矩形的颜色填充块
4.<stroke android:width="1dp">: 1个单位宽度的矩形线
5.corners android:radius="15dp": 矩形的边角曲率15个单位

[报错]:
1.Variable 'intent' might not have been initialized: 变量intent没有初始化

2.6 复选框 CheckBox

  • 常用属性
  • 自定义样式
  • 监听事件

2.6.1 线性垂直布局 + 复选框基本语法

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical"
  android:layout_below="@id/cb_6"
  android:layout_marginTop="20dp">

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:text="你的兴趣:"
    android:textColor="#000"/>

  <CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/cb_7"
    android:text="编程"
    android:textSize="20sp"
    android:layout_marginTop="5sp" />

  <CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/cb_8"
    android:text="编程"
    android:textSize="20sp"
    android:layout_marginTop="5sp"/>

</LinearLayout>

2.6.2 制作带图标的复选框

1.准备好2个图标 icon1icon2
2.将2个图标放入res/drawable-xxhdpi
3.准备选择器: bg_check.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:state_checked="false"
    android:drawable="@drawable/icon_checkbox_false" />
  <item
    android:state_checked="true"
    android:drawable="@drawable/icon_checkbox_true" />
</selector>

[说明] :

  • (1)android:state_checked='false': 未选中
  • (2)android:drawble='@drawable/icon_checkbox_false': 使用icon_checkbox_false图标

4.在CheckBox中使用 Selector: bg_check.xml

<CheckBox
  ...
  android:button="@drawable/bg_check"
>

2.6.3 给复选框添加事件

1.假设复选框的id为 cb_1cb_2
2.编写复选框的活动如下: CheckBoxActivity.java

public class CheckBoxActivity extends AppCompatActivity {
  // 声明控件
  private  CheckBox mCb1, mCb2;
  @override
  protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);

    // 获取控件的视图
    mCb1 = (CheckBox) findViewById(R.id.cb_1);
    mCb2 = (CheckBox) findViewById(R.id.cb_2);

    mCb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
      @override
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        Toast.makeText(CheckBoxActivity.this, isChecked? '1选中': '1取消', Toast.LENGTH_SHORT).show();
      }
    })
    mCb2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
      @override
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        Toast.makeText(CheckBoxActivity.this, isChecked? '2选中': '2取消', Toast.LENGTH_SHORT).show();
      }
    })
  }
}

2.7 ImageView

  • Button的其他衍生控件: ToggleButton、Switch(略)
  • 常用属性
  • 加载网络图片

2.7.1 最基本的ImageView语法

  • activity_image_view.xml
<ImageView
  android:layout_width="300dp"
  android:layout_height="200dp"
  android:background="#ff9900"
  android:src="@drawable/bg_icon_man"
  android:scaleType="fixXY"/>

[说明] :
1.android:scaleType="fixXY": 撑满控件,宽高比可能发生变化
2.android:scaleType="fitCenter": 保持宽高比缩放,直到能完全显示
3.android:scaleType="centerCrop": 保持宽高比缩放,直至完全覆盖控件,裁剪显示

2.7.2 使用ImageView加载一张网络图片

1.写好控件: activity_image_view.xml

<ImageView
  android:id="@+id/iv_4"
  android:layout_width="200dp"
  android:layout_height="100dp"/>

2.配置glide: /app/build.gradle

repositories {
    mavenCentral()
    google()
}
dependencies {
    implementation 'com.github.bumptech.glide:glide:4.10.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
}

[说明] :

  • (1)使用glide进行网络资源请求
  • (2)Android Studio编译器可以自动的按照 build.gradle 中的配置进行Jar包同步

3.获取控件iv_4,并使用glide往里面加资源

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import com.bumptech.glide.Glide;

public class ImageViewActivity extends AppCompatActivity {
  private ImageView mIv4;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_image_view);
    mIv4 = (ImageView) findViewById(R.id.iv_4);
    Glide.with(this).load("https://www.baidu.com/img/bd_logo1.png").into(mIv4);
  }
}

[报错] :

  • 1)Request threw uncaught throwable java.lang.SecurityException: Permission denied (missing INTERNET permission?): 使用glide进行网络请求时,需要配置权限.在路径/app/src/main/AndroidMainfest.xml中添加网络权限如下:
<use-permission android:name="android.permission.INTERNET"  />

2.8 列表视图ListView(知道,被RecyclerView替代)

  • 常用属性
  • Adapter接口
  • Demo演示

2.8.1 创建一个ListViewActivity(手动导入依赖)

  • 1)在com.skypan.textview包下,新建一个包listview
  • 2)在listview下,新建一个Java类.注意: Name: ListViewActivitySuperclass: android.app.Activity
  • 3)创建视图: activity_listview.xml, 在路径 /app/src/main/res/layout
  • 4)完善ListViewActivity.java:
package com.skypan.textview.listview;
import android.app.Activity;
import andoird.os.Bundle;
import androidx.annotation.Nullable;
import com.skypan.textview.R;

public class ListViewActivity extends Activity {
  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_listview);
  }
}
  • 5)将AndroidManifex.xml声明ListViewActivity.java
<activity android:name=".listview.ListViewActivity" />

2.8.2 自定义颜色 + 使用

  • 1)在/app/src/main/res/values/colors.xml中写入自定义颜色,如下
<resources>
  <color name="colorGray">#D5D5D5</color>
</resources>
  • 2)使用
<TextView
  android:textColor="@color/colorGrayDark" />

2.8.3 自定义List View 按压样式

  • 1)新建一个选择器(Selector): /app/src/main/res/drawable -> new Drawable Resource file -> layout_list_item.xml
  • 2)list_item.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@color/colorAcecent" android:state_pressed="true" />
  <item android:drawable="@color/colorWhite" android:state_pressed="false" />
</selector>
  • 3)在List View中使用: activity_listview.xml
<ListView
  android:id="@+id/lv_1"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:listSelector="@drawable/list_item" />

2.8.4 List View的点击事件

[参数]:

  • 1)setOnItemClickListener: 点击事件
  • 2)setOnItemLongClickListener: 长按事件
import android.app.Activity;
import android.os.Bundle;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.ListView

public class ListViewActivity extends Activity {

  // 声明 ListView控件
  private ListView mLv1;

  @Override
  protected void onCrete(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_listview);
    mLv1 = (ListView) findViewById(R.id.lv_1);
    mLv1.setAdapter(new MyListAdapter(ListViewActivity.this));
    mLv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(ListViewActivity.this, text:"点击了" + position, Toast.LENGTH_SHORT).show();
      }
    });
  }
}

[说明] :

  • 1)公有类ListViewActivity继承安卓的app下面的公有类Activity
  • 2)ListView来自Android.widget.ListView
  • 3)适配器类MyListAdapter代码如下:@/src/main/java/com.skypan.textview/listview/MyListAdapter.java
package com.skypan.textview.listview;

import android.widget.BaseAdapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.TextView;
import android.view.View;
import android.view.ViewGroup;

import com.bumptech.glide.Glide;
import com.skypan.textview.R;

public class MyListAdapter extends BaseAdapter {

  private Context mContext;
  private LayoutInflater mLayoutInflater;

  public MyListAdapter(Context context) {
    this.mContext = context;
    mLayoutInflater = LayoutInflater.from(context);
  }

  @Override
  public int getCount() { return 10; }

  @Override
  public Object getItem(int position) { return null; }

  @Override
  public long getItemId(int position) { return 0; }

  static class ViewHolders {
    public ImageView imageView;
    public TextView tvTitle, tvTime, tvContent;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    if(convertView == null) {
      convertView = mLayoutInflater.inflate(R.layout.layout_list_item, null);
      holder = new ViewHolder();
      holder.imageView = (ImageView) convertView.findViewById(R.id.iv);
      holder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
      hodler.tvTime = (TextView) convertView.findViewById(R.id.tv_time);
      hodler.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
      convertView.setTag(holder);
    } else {
      holder = (ViewHolder) convertView.getTag();
    }
    // 给控件赋值
    holder.tvTitle.setText('这是标题');
    holder.tvTime.setText('2088-08-08');
    holder.tvContent.setText('这是内容呐~!');
    Glide.with(mContext).load("https://www.baidu.com/img/bd_logo1.png").into(holder.imageView);
    return convertView;
  }
}

2.x TCP的三次握手与四次挥手

  • 原址
  • 1)请画出三次握手和四次挥手的示意图(略)
  • 2)为什么连接的时候是三次握手?
    参考

[try]:

  • (1)TCP作为一种可靠传输控制协议,其核心思想是: 既要保证数据可靠传输,又要提高传输的效率,而用三次恰恰可以满足以上两种方法.

  • (2)TCP可靠传输的精髓,TCP连接的一方A,由操作系统动态随机选取一个32位长的序列号(Initial Sequelize Number),假设A的初始序列号为1000,以该序列号为原点,对自己将要发送的每个字节的数据进行编号,1001,1002,1003…,并把自己的初始序号ISN告诉B,告诉B什么样编号的数据是合法的,什么编号的数据是非合法的,同时B还可以对A每一个编号的字节数据进行确认。如果A收到B的确认编号2001,则意味着字节编号1001~2000,共1000个字节已经安全到达

  • 3)什么是半连接队列?
    [try]: 在TCP三次握手中的第一次握手,客户端向服务器发送SYN包,客户端将该连接保存在半连接队列中

  • 4)ISN(Initial Sequence Number)是固定的吗?
    [try]: 不是固定的,随机ISN能避免非同一网络的攻击

  • 5)三次握手过程可以携带数据吗?
    [try]: 根据RFC793标准,TCP的前2次握手不允许携带数据,但是第三次握手允许携带数据

  • 6)如果第三次握手丢失了,客户端/服务端 会如何处理?
    参考

[try]:

  • (1)Server端: 此时Server端的状态为SYN_RECV,并且会根据TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送 SYN + ACK 包,以便Client重新发送ACK包.而Server重发SYN + ACK包的次数,可以通过设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5.如果重发次数达到指定的次数仍未收到client的ACK应答,那么一段时间后,Server自动关闭这个连接.
  • (2)Client端: Linux C中,client接收到 SYN + ACK包之后,它的TCP状态就为established,表示该连接已经建立.如果第三次握手中的ACK包丢失的情况下,Client向Server端发送数据,Server端将以RST包响应,方能感知Server的错误.
  • 7)SYN攻击是什么?
    [try]: TCP连接建立时,只发送 SYN包, 而不发送 ACK包.
  • 8)挥手为什么需要四次? (后面解读)
  • 9)四次挥手释放连接时,等待2MSL的意义? (后面解读)

2.x.x TCP全连接/半连接队列

  • 原址

  • 1)什么是半连接队列,全连接队列?
    [a] Linux内核协议栈为一个tcp连接管理使用两个队列,一个是半连接队列(用来保存SYN_SEN和SYN_RECV状态的请求),一个是全连接队列(acceptd队列)(用来保存处于established状态,但是应用层没有调用accept取走的请求.)

  • 2)TCP连接基本概念

    • 三次握手
      (1)第一次握手: 客户端发送syn包(syn=i)到服务器,并进入SYN_SEND状态,并等待服务器确认;
      (2)第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=j+1), 同时也发送一个SYN包(syn=k), 即SYN + ACK包, 此时服务器进入 SYN_RECV 状态.
      (3)第三次握手: 客户端收到服务器的 SYN + ACK包,向服务器发送ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手.
  • 3)半连接队列(sync queue) 和 全连接队列(accept queue)

    • (1)sync queue: 是服务器接收到客户端的第一次握手请求SYN后,将该连接加入到队列中,当收到客户端的ACK后,从列表中移出
    • (2)accept queue: 是服务器收到客户端ACK后,将连接加入到的队列,在连接进行accept处理后,从队列中移出.
  • 4)黑客攻击 - SYN洪水(SYN FLOOD)

    • SYN攻击属于DOS攻击的一种,它利用TCP协议缺陷,通过发送大量的SYN请求,而不回复ACK,占用大量服务器的半连接队列资源,进而导致队列溢出,无法响应正常的连接请求,耗费CPU和内存资源.
发布了177 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/piano9425/article/details/103878287