一、题目:设计一个APP。

1.设计一个APP。
(1)APP中有两个界面。
(2)主界面(MainActiivity)上有“登录”和“广播”两个按钮。点击“登录”按钮,可以打开一个新界面(NewActiivity)。点击“广播”按钮,可以发出广播消息。
(3)新界面(NewActiivity)上可以输入学生姓名、学号、专业班级等信息,另外有“确认”和“取消”两个按钮。当点击“确认”按钮后,可以将学生姓名和学号传递回主界面,并且在主界面上显示传递过来的信息。当点击“取消”按钮后,返回主界面,不带回任何数据信息。
2. 在主界面(MainActiivity)中添加选项菜单,菜单的点击逻辑和按钮的点击逻辑一致(跳转到新界面(NewActiivity))。

二、界面显示



三、主页面详解

本次的代码实现有些复杂,但是好在网上的案例还是很多的,只是脑子转不过来,然后做了一个星期,但是完全做出来之后发现是自己当时智障了。
这个APP的内容可以主要分为三个部分:页面跳转、Intent传送数据、广播。

如上图所示,我们要创建4个Java文件,主页面MainActivity、子页面1NextActivity、子页面2Ne2Activity和广播接收BroadcastActivity。在这里,只有主页面MainActivity、子页面1NextActivity、子页面2Ne2Activity这三个是会当作页面显示用的,广播接收BroadcastActivity是为了作获取子页面2的数据然后显示弹窗返回的。

在主页面中,我们首先要设置两个静态全局变量作为子页面对主页面的返回标志。

    private static final int SUBACTIVITY1 = 1;private static final int SUBACTIVITY2 = 2;

然后建立两个按键的监听器,分别控制“登录”按钮和“广播”按钮,在监听器中写需要传值代码和返回主页面的代码,这里的传值我们用到了向上传值,startActivityForResult()带数据返回主页面。

//假设有一个MainActivity 和 NextActivity ,现在MainActivity启动NextActivity后,我们希望NextActivity给MainActivity传值(这个传值过程就叫向上传值)
Intent intent = new Intent(MainActivity.this, NextActivity.class);//首先在MainActivity里发送数据请求码
startActivityForResult(intent, SUBACTIVITY1);//第二个值是请求码Key

除此之外,我们还要在主页面的代码中写相关代码使子页面的数据成功返回到主页面。这里有两个方法,一个是利用回调函数onActivityResult()实现、另一个是直接在onCreate()函数下实现数据的获取,但这两者的使用都用到Intent(意图),其主要功能是解决 Android 中各项组件之间的通讯 。
方法一:onActivityResult()实现

 /*** requestCode和startActivityForResult中的requestCode相对应* resultCode和Intent由SubActivity通过其setResult()方法返回**/@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch(requestCode){case SUBACTIVITY1:if (resultCode == RESULT_OK){Uri uriData = data.getData();textView.setText(uriData.toString());break;case SUBACTIVITY2:break;}}

代码含义:当页面收到SUBACTIVITY1这个请求码时,如果子页面中的结果码等等于RESULT_OK,这个时候我们用Uri定义一个uriData,并将子页面中的数据赋值给uriData,再用setText在主页面上显示数据,并用toString()将数据转成String类型;如果请求码为SUBACTIVITY2,就认为是RESULT_CANCELED,此时不带回数据返回主页面。
这里的onActivityResult()函数要继承onActivityResult父类,并需要请求码requestCode、结果码resultCode和数据data这三个参数。
在书上和网上都告诉我们这三个参数的含义,这里我引用一篇博客的文字,链接见文末《Android onActivityResult()的属性与用法》:

这三个参数的含义如下:
requestCode:请求码,用于启动子Activity
resultCode:子Activity设置的结果码,用于指示操作结果。可以是任何整数值,但通常是resultCode = =
RESULT_OK或resultCode==RESULT_CANCELED
Data:用于打包返回数据的Intent,可以包括用于表示所选内容的URI。子Activity也可以在返回数据Intent时,添加一些附加消息。

方法二:onCreate()实现

public class MainActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Intent intent = getIntent();String name = intent.getStringExtra("editText");String num = intent.getStringExtra("editText2");String proclass = intent.getStringExtra("editText3");textView.setText(String.valueOf(name));textView2.setText(String.valueOf(num));textView3.setText(String.valueOf(proclass));}
}

在方法二中,我们直接用getIntent()来获取数据,并将获取到的数据返回到我们定义的Intent中,接着用到getStringExtra获得同意工程下其他Java文件的数据,这里引号内的内容是我们要获取其数据的键名。
后面的String.valueOf()的意思是将name(num 、proclass)里的内容转成String类。
个人感觉跟第一种toString()方法相比,String.valueOf()像是一个间接寻址的过程。

四、子页面1详解

从题目可以看出,我们要从子页面1中输入学生的姓名、学号和专业班级,这说明要用到EditText控件,读取和撤销则要用到Button按钮。

关于子页面1的Java文件,button照常是要用到监听器去监听的。因为读取的按钮负责要把我们输入的数据传回到主页面去,所以要在读取的按钮监听器中添加Intent()方法,然后放数据进intent里。
在这里我们要用到putExtra(name,value)把数据放进去。
这里的putExtra相当于可以把数据放在可以发送到别的Java文件中的函数,如果只有put的话,说明就只能在当前的Java文件下get(获取)我们存入的数据。name是键名,相当于一个“暗号”,当我们在别的Java文件下输入这个键名,就可以跟这里的内容“对上暗号”,value是键值,用来存放我们输入的数据,当我们从别的Java文件中对上暗号,就可以传送键值中的数据。
子页面1局部Java代码如下(注意:这里的代码对应上面主页面详解的方法二):

 btnSign.setOnClickListener(new View.OnClickListener(){public void onClick(View view){String uriString = editText.getText().toString();String uriString2 = editText2.getText().toString();String uriString3 = editText3.getText().toString();Intent intent = new Intent();intent.putExtra("editText",uriString);intent.putExtra("editText2",uriString2);intent.putExtra("editText3",uriString3);intent.setClass(SubActivity1.this,MainActivity.class);startActivity(intent);}});

那么对应主页面方法一的代码怎么写呢?
代码如下所示,下面的代码我们定义了一个Uri类型去存放我们的数据,利用parse方法访问我们的本地资源,这里的资源名字定义为uriString。

btnSign.setOnClickListener(new View.OnClickListener(){public void onClick(View view){String uriString = editText.getText().toString()+"   "+editText2.getText().toString()+"   "+editText3.getText().toString();//parse方法返回的是一个Uri类型,通过这个Uri可以访问一个网络上或者是本地的资源Uri data = Uri.parse(uriString);Intent result = new Intent(null, data);setResult(RESULT_OK, result);//第一个参数是系统的KEY ,判断传值是否成功finish();}});

这两个方法到最后的输出显示有什么区别呢?
如下图:


↑ ↑ ↑这是用putExtra方法传送数据的页面显示。


↑ ↑ ↑这是用parse方法传送数据的页面显示。
可以看出来,我们可以用①去分别返回我们我们的三个数据;而②则是用下面这行代码去把我们的三个数据连起来存放到一个data中,这样输出其实是一个data,但是我们可以用空格来将它们分开,让我们看起来的时候变成了三个数据(就是说我们看上去是三个数据,但在代码中它其实只是一个数据)。

String uriString = editText.getText().toString()+"   "+editText2.getText().toString()+"   "+editText3.getText().toString();

当我们不想要传回任何数据要主页时,我们则点击撤销按钮。
撤销的按钮不带回任何数据,所以我们在监听器里写上RESULT_CANCELED结果码就好了,返回的是空值(null)。

        btnRe.setOnClickListener(new View.OnClickListener(){public void onClick(View view){setResult(RESULT_CANCELED, null);finish();}});

五、 子页面2详解

子页面2用到了广播去发送数据,在这里,我们需要创建两个Java文件,一个是用来发送广播,一个是用来接收广播。
我们一般用Intent发送广播消息,广播消息的内容可以是应用程序密切相关的数据信息,也可以是Android的系统信息,当应用程序注册了BroadcastReceiver,则可以接收指定的广播消息。
在我所学的教材中有这么一段话:

使用Intent发送广播消息非常简单,只需创建一个Intent,并调用sendBroadcast()函数就可把Intent携带的信息广播出去。但需要注意的是,在构造Intent时必须定义一个全局唯一的字符串,用来标识其要执行的动作,通常使用应用程序包的名称。如果要在Intent传递额外数据,可以用Intent的putExtra()方法。

如教材中所述,我们需要在按键的监听器中定义一个全局唯一的字符串,用来标识其要执行的动作,并用到putExtra发送数据。
代码如下:

btnbro.setOnClickListener(new View.OnClickListener(){public void onClick(View view){Intent intent = new Intent("com.mwt.mwtclass3rd");intent.putExtra("showmess",ent2.getText().toString());sendBroadcast(intent);}});

而在接收广播消息时,我们则需要继承BroadcastReceiver类,并重载onReceive()方法。
在这次的APP中,返回的广播用到浮窗来显示。
广播接收的代码:

public class BroActivity extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent){//TODO Auto-generated method stubString msg=intent.getStringExtra("showmess");Toast.makeText(context,msg,Toast.LENGTH_LONG).show();}
}

广播消息这就结束了吗?不然,我们还要在AndroidMani.xml文件中注册一个BroadcastReceiver,否则我们是收不到我们要发送的消息的。
这里的广播注册用到了<intent-filter>去注册静态广播,也有动态广播,感兴趣的可以去找找动态广播的使用案例。
但是,用到静态广播的话,我们必须要在Android8.0以下的系统去运行,因为自Android8.0开始,谷歌为了提高用户的系统性能,取消了大部分的静态广播功能。

        <receiverandroid:name=".BroActivity"android:exported="true"><intent-filter><action android:name="com.mwt.mwtclass3rd"/></intent-filter></receiver>

同时,我们还要在该文件下的manifest控件中写入<uses-sdk android:maxSdkVersion="14"/>。在这里,uses-sdk是用来设置APP对Android系统的兼容性的,这里的14则能够保证我们的APP能在所有Android系统内100%兼容。

六、Java代码

主页面Java代码1

package com.mwt.testmaxing;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.net.DatagramPacket;public class MainActivity extends Activity {private static final int SUBACTIVITY1 = 1;private static final int SUBACTIVITY2 = 2;TextView textView,textView2,textView3;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = (TextView)findViewById(R.id.label1);textView2 = (TextView) findViewById(R.id.label2);textView3 = (TextView) findViewById(R.id.label3);final Button btn1 = (Button)findViewById(R.id.btn1);final Button btn2 = (Button)findViewById(R.id.btn2);btn1.setOnClickListener(new View.OnClickListener(){public void onClick(View view){//假设有一个MainActivity 和 NextActivity ,现在MainActivity启动NextActivity后,我们希望NextActivity给MainActivity传值(这个传值过程就叫向上传值)//首先在MainActivity里发送数据请求码Intent intent = new Intent(MainActivity.this, NextActivity.class);startActivityForResult(intent, SUBACTIVITY1https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343);//第二个值是请求码Key}});btn2.setOnClickListener(new View.OnClickListener(){public void onClick(View view){Intent intent = new Intent(MainActivity.this, Ne2Activity.class);startActivityForResult(intent, SUBACTIVITY2);}});}/*** requestCode和startActivityForResult中的requestCode相对应* resultCode和Intent由SubActivity通过其setResult()方法返回**/@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch(requestCode){case SUBACTIVITY1:if (resultCode == RESULT_OK){Uri uriData = data.getData();textView.setText(uriData.toString(https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343));}break;case SUBACTIVITY2:break;}}
}

子页面Java代码1

package com.mwt.testmaxing;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;public class NextActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_next);https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343final EditText editText = (EditText)findViewById(R.id.entry1);final EditText editText2 = (EditText)findViewById(R.id.entry2);final EditText editText3 = (EditText)findViewById(R.id.entry3);Button btnSign = (Button)findViewById(R.id.get);Button btnRe = (Button)findViewById(R.id.cancel);btnSign.setOnClickListener(new View.OnClickListener(){public void onClick(View view){String uriString = editText.getText().toString()+"   "+editText2.getText().toString()+"   "+editText3.getText().https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343toString();//parse方法返回的是一个Uri类型,通过这个Uri可以访问一个网络上或者是本地的资源Uri data = Uri.parse(uriString);Intent result = new Intent(null, data);https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343setResult(RESULT_OK, result);//第一个参数是系统的KEY ,判断传值是否成功finish();}});btnRe.setOnClickListener(new View.OnClickListener(){public void onClick(View view){setResult(RESULT_CANCELED, null);finish();}});}
}

主页面Java代码2

package com.mwt.mwtclass3rd;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends Activity {private static final int SUBACTIVITY1 = 1;private static final int SUBACTIVITY2 = 2;TextView textView,textView2,textView3;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = (TextView)findViewById(R.id.label1);textView2 = (TextView) findViewById(R.id.label2);textView3= (TextView) findViewById(R.id.label3);final Button btn1 = (Button)findViewById(R.id.btn1);final Button btn2 = (Button)findViewById(R.id.btn2);Intent intent = getIntent();String name = intent.getStringExtra("editText");String num = intent.getStringExtra("editText2");String proclass = intent.getStringExtra("editText3");textView.setText(String.valueOf(name));textView2.setText(String.valueOf(num));textView3.setText(String.valueOf(proclass));btn1.setOnClickListener(new View.OnClickListener(){public void onClick(View view){//向上传值Intent intent = new Intent(MainActivity.this, SubActivity1.class);https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343//页面跳转startActivityForResult(intent, SUBACTIVITY1);}});btn2.setOnClickListener(new View.OnClickListener(){public void onClick(View view){Intent intent = new Intent(MainActivity.this, SubActivity2.https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343class);startActivityForResult(intent, SUBACTIVITY2);}});}}

子页面1Java代码2

package com.mwt.mwtclass3rd;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;public class SubActivity1 extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sub1);final EditText editText = (EditText)findViewById(R.id.entry1);final EditText editText2 = (EditText)findViewById(R.id.entry2);final EditText editText3 = (EditText)findViewById(R.id.entry3);Button btnSign = (Button)findViewById(R.id.get);Button btnRe = (Button)findViewById(R.id.cancel);btnSign.setOnClickListener(new View.OnClickListener(){public void onClick(View view){String uriString = editText.getText().toString();String uriString2 = editText2.getText().toString();String uriString3 = editText3.getText().toString();Intent intent = new Intent();intent.putExtra("editText",uriString);intent.putExtra("editText2",uriString2);intent.putExtra("editText3",uriString3);intent.setClass(SubActivity1.this,MainActivityhttps://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343.class);startActivity(intent);}});btnRe.setOnClickListener(new View.OnClickListener(){public void onClick(View view){setResult(RESULT_CANCELED, null);finish();}});}
}

子页面2代码

package com.mwt.mwtclass3rd;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SubActivity2 extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sub2);Button btnbro = (Button)findViewById(R.id.btn_Bro);EditText ent2 = (EditText) findViewById(R.id.writemes);Button btnReturn = (Button)findViewById(R.id.btn_return);btnbro.setOnClickListener(new View.OnClickListener(){public void onClick(View view){Intent intent = new Intent("com.mwt.mwtclass3rd");intent.putExtra("showmess",ent2.getText().toString()https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343);sendBroadcast(intent);}});btnReturn.setOnClickListener(new View.OnClickListener(){public void onClick(View view){setResult(RESULT_CANCELED, null);finish();}});}
}

广播接收页面Java代码

package com.mwt.mwtclass3rd;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;public class BroActivity extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent){//TODO Auto-generated method stubString msg=intent.https://blog.csdn.net/kiro_1023?spm=1001.2101.3001.5343getStringExtra("showmess");Toast.makeText(context,msg,Toast.LENGTH_LONG).show();}
}

七、演示



八、流水账

这次的上机课难度确实上来了,当时一直卡在子页面1的数据回传功能这块上,老师给的是书上的代码,也就是用请求码、结果码和数据来返回我们输入的数据,而网上大多是直接重载onCreate()来getIntent()我们的数据,个人感觉后者比较好用。
当时首先是被BroadcastReceiver卡了一下,怎么也收不到发出去的广播,后面查了相关资料才知道谷歌为了提高用户的系统性能,自Android8.0开始,取消了大部分的静态广播功能,而课上讲的刚好是要用静态广播去发送广播的,为了节省时间,我也没有去学习动态广播的使用方法,而是直接将模拟器中最开始的Android11.0系统设置为Android5.0系统。然后便是漫长地找为什么子页面1不能传回多个数据到主页面上的解决方法。
后来终于解决了这个问题:因为我一开始是直接抄老师课堂上讲的代码用的是onActivityResult方法,但是网上是直接用getIntent方法的,本来想要把网上的方法直接放到onActivityResult里面去,但是不行,问了老师后老师让我用putExtra方法和getExtra,但是用了它后无论输入数据主页面都只能返回“null”,就这样null了一天,我又去问了老师,老师说我代码没错,按道理来说不应该会只返回“null”,无奈之下让我把三个数据放到一个data里面。我也试了,但是返回的数据会连起来,不太好看,我把这件事情告诉了班上的同学,同学给我示范了一下——他把连起来的数据之间加了个+“ ”+,这样输出确实好看点了,但我还是觉得怪怪的。
昨晚无聊继续看网上的方法,直接把抄老师的代码删掉,再写一遍,就好了… …
挺难过的,因为这八天来我像个弱智。

参考

android studio将一个页面信息传送到另一个页面并显示
Android四大组件——BroadcastReceiver(原理篇)
Android 8.0新特性-取消大部分静态注册广播
Android 8.0 行为变更
Android BroadcastReceiver:接收广播
配置 Android Studio
Android onActivityResult()的属性与用法
Android数据存储之SharedPreferences
android 开发 Intent使用技巧点
【Android开发】intent.putExtra()方法参数详解及示例

移动终端应用开发上机3组件通信与广播相关推荐

  1. 移动终端应用开发上机4服务与数据存储

    一.题目:设计一个APP 1.设计一个APP. (1)APP中有四个界面. (2)主界面(MainActivity)上有选项菜单,包含三个菜单项:"SD卡存储"."启动信 ...

  2. 【Vue 组件化开发 三】父组件给子组件传递数据、组件通信(父传子、子传父)、父访问子(children、ref)、动态组件(is、component)

    目录 一.前言 完整内容请关注: 二.父组件给子组件传递数据 1.使用props属性,父组件向子组件传递数据 1.使用组件的props属性 2.向cmessage对象传值 2. props属性使用 1 ...

  3. Android程序猿必看之《终端应用开发指南》

    一.前言 4G移动网络的商用为移动互联网的蓬勃生长提供了肥沃的土壤,并协同国内外众多互联网厂商及终端厂商共同引领了中国移动互联网翻天覆地的发展与创新. 2014年以来移动4G用户数目显著提升,拉动了全 ...

  4. angularjs1访问子组件_vue 组件通信看这篇就够了(12种通信方式)

    vue 组件间的通信是 vue 开发中很基础也十分重要的部分,作为使用 vue 的开发者每天都在使用.同时,vue 通信也是面试中非常高频的问题,有很多面试题,都是围绕通信展开. 本文会介绍常见的通信 ...

  5. 【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | 完整代码示例 )

    文章目录 前言 一.Android 端完整代码示例 二.Flutter 端完整代码示例 三.相关资源 前言 前置博客 : [Flutter]Flutter 混合开发 ( Flutter 与 Nativ ...

  6. vue 改变domclass_基于 vue 开发甘特图组件的心路历程(兼设计分享)

    语雀原文 有更好的排版体验~ 这篇文章主要讲述笔者开发 v-gantt 甘特图组件的经过. 起源 公司项目有个甘特图的需求. 笔者考察了世面上 常见的甘特图组件 后,本着 我上我也行 的心态,以及考虑 ...

  7. DSP:6678开发板NDK网口通信完整实现(附源码)

    如果出现图片打不开,或是显示异常,请点击下方链接阅读原文!!! DSP:6678开发板NDK网口通信完整实现(附源码) - 子木的文章 - 知乎 https://zhuanlan.zhihu.com/ ...

  8. value数字 vue_基于Vue开发数字输入框组件

    随着 vue 越来越火热, 相关组件库也非常多啦, 只用轮子怎么够, 还是要造起来!!! 1.概述 vue组件开发的api:props.events和slots 2.组件代码 效果: (1)index ...

  9. export default用法vue_Vue组件通信—provide/inject

    前言: 之前在 Vue 中进行组件通信一般都会使用 props,开始使用 provide/inject 是非常偶然的一次尝试. 当时在开发中需要实现祖孙组件,甚至祖祖祖祖孙组件之间的通信,在这种多层级 ...

最新文章

  1. Matlab读取文本数据
  2. Alter操作(修改列名,修改列数据类型,增加列,删除列,增加列且设为主键及对默认值操作)
  3. mysql批量用trim限定_mybatis中批量更新sql语句,trim、foreach标签,varchar定义理解
  4. (39)VHDL实现移位寄存器(方法1)
  5. 使用oracle/mysql/tidb由空格引发的血案解析
  6. Java打包生成exe(使用exe4j和inno setup)
  7. 使用FlashFTP上传文件到指定服务器
  8. Python 颜色选择器
  9. NOD32企业内部更新服务器搭建
  10. 安卓(android)毕业设计各种app项目
  11. Taulia任命Todd Musselman为首席福祉官
  12. iOS 音乐 锁屏显示 控制
  13. 如何在电脑上下载python中文版_Python下载-Python中文版官方下载
  14. 架构设计:系统存储(21)——图片服务器:详细设计(1)
  15. 哔哩哔哩2020校园招聘前端笔试卷(一)
  16. python模拟登录网站_Python爬虫实战之(四)| 模拟登录京东商城
  17. 常用的java工具类
  18. java构造方法:有参构造方法和无参构造方法区别
  19. 农业物联网的六大应用场景
  20. 聊一聊DNS劫持那些事

热门文章

  1. Oracle数据库(四)备份与还原
  2. 图文详解Unity3D中Material的Tiling和Offset是怎么回事
  3. Illumina测序什么时候会测序到接头序列?
  4. 团体程序设计天梯赛-练习集-L1-031. 到底是不是太胖了
  5. pc构件生产线及设备_PC构件生产线全套设备清单
  6. 微信小程序上传Excel文件并分析上传值数据库
  7. SDH与SONET(整理)
  8. 优美库图片小程序 Version1.0
  9. python第一天----爬取优美图库的图片
  10. STM32开发笔记03---Bit-Banding