前言

  啦啦啦~(博主每次开篇都要卖个萌,大家是不是都厌倦了呢~)

  本篇博文希望帮助大家掌握 Broadcast 编程基础,实现动态注册 Broadcast 和静态注册 Broadcast 的方式以及学会使用Notification。

基础知识

  BraodcastReceiver(广播接收器)是为了实现系统广播(Notification)而提供的一种组件, 它和事件处理机制类似,但是事件处理机制是程序组件级别的,而广播事件处理 机制是系统级别的。比如,我们可以发出一种广播来测试手机电量的变化,这时候就可以定义一个 BraodcastReceiver 来接受广播,当手机电量较低时提示用户。它是一个系统全局的监听器,用于监听系统全局的Broadcast消息,所以它可以很方便的进行系统组件之间的通信。

  BroadcastReceiver虽然是一个监听器,但是它和之前用到的OnXxxListener不同,那些只是程序级别的监听器,运行在指定程序的所在进程中,当程序退出的时候,OnXxxListener监听器也就随之关闭了,但是BroadcastReceiver属于系统级的监听器,它拥有自己的进程,只要存在与之匹配的Broadcast被以Intent的形式发送出来,BroadcastReceiver就会被激活。

  虽然同属Android的四大组件,BroadcastReceiver也有自己独立的声明周期,但是和Activity、Service又不同。当在系统注册一个BroadcastReceiver之后,每次系统以一个Intent的形式发布Broadcast的时候,系统都会创建与之对应的BroadcastReceiver广播接收者实例,并自动触发它的onReceive()方法,当onReceive()方法被执行完成之后,BroadcastReceiver的实例就会被销毁。虽然它独自享用一个单独的进程,但也不是没有限制的,如果BroadcastReceiver.onReceive()方法不能在10秒内执行完成,Android系统就会认为该BroadcastReceiver对象无响应,然后弹出ANR(Application No Response)对话框,所以不要在BroadcastReceiver.onReceive()方法内执行一些耗时的操作。

  如果需要根据广播内容完成一些耗时的操作,一般考虑通过Intent启动一个Service来完成该操作,而不应该在BroadcastReceiver中开启一个新线程完成耗时的操作,因为BroadcastReceiver本身的生命周期很短,可能出现的情况是子线程还没有结束,BroadcastReceiver就已经退出的情况,而如果BroadcastReceiver所在的进程结束了,该线程就会被标记为一个空线程,根据Android的内存管理策略,在系统内存紧张的时候,会按照优先级,结束优先级低的线程,而空线程无异是优先级最低的,这样就可能导致BroadcastReceiver启动的子线程不能执行完成。

  BroadcastReceiver本质上还是一个监听器,所以使用BroadcastReceiver的方法也是非常简单,只需要继承BroadcastReceiver,在其中重写onReceive(Context context,Intent intent)即可。一旦实现了BroadcastReceiver,并部署到系统中后,就可以在系统的任何位置,通过sendBroadcast、sendOrderedBroadcast方法发送Broadcast给这个BroadcastReceiver。

  我们既可以用 Intent 来启动一个组件,也可以用 sendBroadcast()方法发起一个系统级别的事件广播来传递消息。我们同样可以在自己的应用程序中实现 BroadcastReceiver 来监听和响应广播的Intent。在程序中使用 BraodcastReceiver 是比较简单的。首先要定义一个类继承 BraodcastReceiver,并且覆盖 onReceiver()方法来响应事件。然后注册在程序中 BraodcastReceiver。最后构建 Intent 对象调用 sendBroadcast()方法将广播发出。

  包含静态注册方式和动态注册方式:

1.静态广播部分

  静态广播部分首先需要后设置 setOnItemClickListener,利用 bundle 和 intent 将图片与文字内容发送出去。

  

  参考代码中的 STATICATION 为自己设定的广播名称。由于是静态注册所以需要在 AndroidMainfest.xml 中进行注册(右击New->other->Broadcast Receiver创建一个Receiver类后,AS将自动在AndroidMainfest.xml 中进行注册,我们只需要添加自己设定的广播名称):

  

  在静态广播类 StaticReceiver 中重写 onReceive 方法,当接收到对应广播时进行数据 处理,产生通知。

  

2.动态注册部分

(1) 实现 BroadcastReceiver 子类(这里命名为 DynamicReceiver),并且重写 onReceive 方法,修改方法与静态广播类中类似。

(2)创建主页面,设置注册和注销按钮(set OnClickListener),使其能够注册或者注销广 播器。

注册关键代码:

注销关键代码:

      其中 dynamicReceiver 为我们之前创建的 DynamicReceiver 类。用 registerReceiver 与 unregisterReceiver 分别对其进行注册与注销。

  (3)设置 Send 按钮点击事件,如果广播注册,则能够点击后发送广播。发送方法与静态注 册时一直,仅需修改广播名称即可。(使用 sendBroadcast(intent))

  (4)注意在 Android 主界面中将 launchMode 设置为 singleInstance,使得点击 Notification 后不会另外新建一个 MainActivity:

  

3.Notification 的使用

  Notification 可以提供持久的通知,位于手机最上层的状态通知栏中。用手指按下状 态栏,并从手机上方向下滑动,就可以打开状态栏查看提示消息。

  通知一般通过NotificationManager服务发送一个Notification对象来完成通知,NotificationManager是一个重要的系统级服务,该对象位于应用程序的框架层中,应用程序可以通过它向系统发送全局的通知。使用通知的时候,需要创建一个Notification对象用来承载通知的内容,但是一般不会直接通过Notification的构造方法来得到对象,而是使用它的内部类Notification.Builder来实例化一个Builder对象,并设置通知的各项属性,最后通过Notification.Builder.builder()方法得到一个Notification对象,当获得这个Notification对象之后,就可以使用NotificationManager.notify()方法发送通知。

 

  开发 Notification 主要 涉及以下 3 个类:

   (1)Notification.Builder:用于动态的设置 Notification 的一些属性。

  

  这里LargeIcon获取的参数通过以下方式来设定(获取图片资源的方式):

  

  虽然通知中提供了各种属性的设置,但是一个通知对象,有几个属性是必须要设置的,其他的属性均是可选的,必须设置的属性如下:

  • 小图标,使用setSamllIcon()方法设置。
  • 标题,使用setContentTitle()方法设置。
  • 文本内容,使用setContentText()方法设置。

    (2)NotificationManager:负责将 Notification 在状态显示出来和取消;

    

  NotificationManager类是一个通知管理器类,这个对象是由系统维护的服务,是以单例模式的方式获得,所以一般并不直接实例化这个对象。在Activity中,可以使用Activity.getSystemService(String)方法获取NotificationManager对象,Activity.getSystemService(String)方法可以通过Android系统级服务的句柄,返回对应的对象。在这里需要返回NotificationManager,所以直接传递Context.NOTIFICATION_SERVICE即可。

    (3)Notification:设置 Notification 的相关属性。

    

  (4)点击 notification,就可以跳转到我们 intent 中指定的 activity。主要使用到setContentIntent 与 PendingIntent。

关于 Notification,不同版本的 API 显示可能会有所不同。本次实验中必须实现的部 分是标题、大图标、内容、小图标。其中标题为静态广播或动态广播;大图标与广播发送的内容相关,为对应水果或者动态图 dynamic;内容为水果名称或动态广播发送的内容; 小图标与大图标内容一样。

图片的使用方面请尽量使用 mipmap 目录下的 image asset。否则在某些 API 中可能会 出现 Icon 过大的情况。

实验内容

实现一个 Android 应用,实现静态广播、动态广播两种改变 Notification 内容的方法。 具体要求:

(1)该界面为应用启动后看到的界面。

(2)点击静态注册按钮,跳转至如下界面。

点击表单项目。如 orange。会有对应通知产生,点击通知返回主界面:

(3)点击动态注册按钮,跳转至如下界面。

        

(未注册广播)                       (已注册广播)                  (已注册后点击发送)

实现以下功能:

a)可以编辑广播的信息,点击 Send 按钮发送广播。 b)设置一个按钮进行广播接收器的注册与注销。 c)广播接收器若已被注册,发送出的广播信息会产生一个对应通知。 d)点击 Notification 可以跳转回主界面。

注:在设置按钮内容的时候注意大小写问题(使用android:textAllCaps="false"属性)。

实验步骤

1.XML 布局

  本实验初始界面的 XML 布局是比较简单的,包括初始界面的两个按钮、静态 注册布局中的 ListView 及其每一栏中的 ImageView TextView、动态布局中的 EditText Button。

2.静态注册部分

  在一个 xml 布局文件中写好一个 ListView(这样就创建了一个空的列表, 然后在.java 文件中再填充数据),在每一栏中的 ImageView TextView 使用线 性结构,分别用来存放图片背景及联系人的姓名。这里和第三次实验类似。  在 MainActivity.java 文件中,我们获取到初始界面的两个按钮并使用 Intent 设置相应的点击跳转事件。

  在 StaticActivity.java 文件中, 我们需要获取到静态注册布局中的 ListView 并使用 Adapter 为这个 ListView 填充数据。我们需要获取图片和名称 两个参数,与实验三不同的是每一栏中的图片背景都不同。首先,我们创建一个Fruit 类,来存储名称数据,初始化一些变量,并使用 get 和 Set 方法来获得或 者更改相应的数据。

    接下来在 StaticActivity.java 文件中为每一项名称数据创建一个对象,并 添加在 List 中,方便之后传递数据的操作。这里我们通过获取图片命名将图片 素材绑定在一个 int 类型的数组中:

    

    首先构建好数据,把数据以 Map 键值对的形式添加到 list 中。然后创建Listview 的 Adapter。

     

    在 ListView 单击事件中,利用 bundle 和 intent 将图片与文字内容发送出去:

    

  创建一个 Broadcast Receiver 类,并在 AndroidMainfest.xml 中进行注册。 然后在静态广播类 StaticReceiver 中重写 onReceive 方法,当接收到对应广 播时进行数据 处理,产生通知。

  这里我们获取到点击产生的图片和文字信息,并使用 Notification(可以 提供持久的通知,位于手机最上层的状态通知栏中。用手指按下状态栏,并从手 机上方向下滑动,就可以打开状态栏查看提示消息)。设置好 Notification 涉 及的 3 个类: Notification.Builder(用于动态的设置)、 NotificationManager (负责将 Notification 在状态显示出来和取消)、Notification(设置 Notification 的相关属性),然后使用 setContentIntent 与 PendingIntent 使得点击 notification,就可以跳转到我们 intent 中指定的 activity:

  

3.动态注册部分:

  在这一部分中有两个按钮,Register Broadcast 按钮再按下后将会变换按 钮文本并实现一些按钮事件,并且再次按下时的事件也会有所改变。受实验三中 星星切换的启发,这里我们可以使用 tag,每个 View 都可以设置 tag,通过 tag 可以用来判断该 View 现在的状态。在初始化的时候,将 tag 设置为 0。然后在 相应位置完成注册和注销按钮功能的设置:

  

  在 send 按钮事件中,也要注意此时 Register Broadcast 按钮的状态问题, 所以也需要使用 tag 来进行判断(设置 Send 按钮点击事件,如果广播注册,则 能够点击后发送广播。发送方法与静态注册时一致,仅需修改广播名称即可。在 这里我们也需获取到 EditText 中获取到的文本,作为传递的参数之一):

相应的,创建一个 Broadcast Receiver 类,并在 AndroidMainfest.xml 中进行 注册。然后在动态广播类中重写 onReceive 方法,当接收到对应广播时进行数 据处理,产生通知。

完成实验~

此外:

  在 Android 主界面中将 launchMode 设置为 singleInstance,使得点击 Notification 后不会另外新建一个 MainActivity;

  为了防止缩图在 mipmap 里新建 image assert,将所有使用的图片都进行创 建。

实验关键代码

StaticActivity.java

package com.example.yanglh6.myapplication4;import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;/*** Created by lenovo on 2016/10/21.*/public class StaticActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.static_layout);final int[] stu_pic = {R.mipmap.apple,R.mipmap.banana,R.mipmap.cherry,R.mipmap.coco,R.mipmap.kiwi,R.mipmap.orange,R.mipmap.pear,R.mipmap.strawberry,R.mipmap.watermelon};final List<Map<String, Object>> data = new ArrayList<>();/*生成动态数组,加入数据*/final List<Fruit> ItemName = new ArrayList<Fruit>();ItemName.add(new Fruit("Apple"));ItemName.add(new Fruit("Banana"));ItemName.add(new Fruit("Cherry"));ItemName.add(new Fruit("Coco"));ItemName.add(new Fruit("Kiwi"));ItemName.add(new Fruit("Orange"));ItemName.add(new Fruit("Pear"));ItemName.add(new Fruit("Strawberry"));ItemName.add(new Fruit("Watermelon"));final String[] name = new String[ItemName.size()];for (int i = 0; i < ItemName.size(); i++) {String x = ItemName.get(i).getItemName();name[i] = x;}for (int i = 0; i < ItemName.size(); i++) {Map<String, Object> temp = new LinkedHashMap<>();temp.put("ItemImage", stu_pic[i]);temp.put("name", name[i]);data.add(temp);}ListView listView = (ListView) findViewById(R.id.staticStart);final SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.item,new String[]{"ItemImage", "name"}, new int[]{R.id.ItemImage, R.id.ItemName});listView.setAdapter(simpleAdapter);/*  ListView单击事件  */listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {Intent intent = new Intent("com.example.yanglh6.myapplication4.staticreceiver");Fruit temp = ItemName.get(i);intent.putExtra("ItemImage", stu_pic[i]);intent.putExtra("name", name[i]);sendBroadcast(intent);}});}
}

StaticReciver.java

package com.example.yanglh6.myapplication4;import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;public class StaticReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (intent.getAction().equals("com.example.yanglh6.myapplication4.staticreceiver")) {Bundle bundle = intent.getExtras();Bitmap bitmap=BitmapFactory.decodeResource(context.getResources(),bundle.getInt("ItemImage"));int imageId = (int) bundle.get("ItemImage");NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);Notification.Builder builder = new Notification.Builder(context);builder.setContentTitle("静态广播").setContentText(bundle.getString("name")).setLargeIcon(bitmap).setSmallIcon(imageId).setTicker("您有一条新消息").setAutoCancel(true);Intent Intent1 = new Intent(context, MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, Intent1, 0);builder.setContentIntent(pendingIntent);Notification notify = builder.build();notificationManager.notify(0, notify);}}
}

DynamicActivity.java

package com.example.yanglh6.myapplication4;import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;/*** Created by lenovo on 2016/10/21.*/public class DynamicActivity extends AppCompatActivity {private boolean tag = false;private DynamicReceiver dynamicReceiver = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.dynamic_layout);final Button buttonRegister = (Button) findViewById(R.id.register);Button buttonSend = (Button) findViewById(R.id.send);buttonRegister.setOnClickListener(new Button.OnClickListener() {@Overridepublic void onClick(View view) {if (!tag) {buttonRegister.setText("Unregister Broadcast");tag = true;dynamicReceiver = new DynamicReceiver();IntentFilter dynamic_filter = new IntentFilter();dynamic_filter.addAction("com.example.yanglh6.myapplication4.dynamicreceiver");registerReceiver(dynamicReceiver, dynamic_filter);} else {buttonRegister.setText("Register Broadcast");tag = false;unregisterReceiver(dynamicReceiver);}}});buttonSend.setOnClickListener(new Button.OnClickListener() {@Overridepublic void onClick(View view) {if (!tag) {} else {Intent intent = new Intent("com.example.yanglh6.myapplication4.dynamicreceiver");String str1 = "";EditText editText = (EditText) findViewById(R.id.editText);str1 = editText.getText().toString();intent.putExtra("ItemImage", R.mipmap.dynamic);intent.putExtra("name", str1);sendBroadcast(intent);}}});}
}

DynamicReceiver.java

package com.example.yanglh6.myapplication4;import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;public class DynamicReceiver extends BroadcastReceiver {public DynamicReceiver() {}@Overridepublic void onReceive(Context context, Intent intent) {if (intent.getAction().equals("com.example.yanglh6.myapplication4.dynamicreceiver")) {Bundle bundle = intent.getExtras();Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), bundle.getInt("ItemImage"));int imageId = (int) bundle.get("ItemImage");NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);Notification.Builder builder = new Notification.Builder(context);builder.setContentTitle("动态广播").setContentText(bundle.getString("name")).setLargeIcon(bitmap).setSmallIcon(imageId).setTicker("您有一条新消息").setAutoCancel(true);Intent mIntent = new Intent(context, MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, mIntent, 0);builder.setContentIntent(pendingIntent);Notification notify = builder.build();notificationManager.notify(0, notify);}}
}

实验截图

  

  

  

  

总结

  BraodcastReceiver(广播接收器)是为了实现系统广播而提供的一种组件, 它和事件处理机制类似,但是事件处理机制是程序组件级别的,而广播事件处理 机制是系统级别的。比如,我们可以发出一种广播来测试手机电量的变化,这时 候就可以定义一个 BraodcastReceiver 来接受广播,当手机电量较低时提示用 户。我们既可以用 Intent 来启动一个组件,也可以用 sendBroadcast()方法发 起一个系统级别的事件广播来传递消息。我们同样可以在自己的应用程序中实现 BroadcastReceiver 来监听和响应广播的 Intent。

  在程序中使用 BraodcastReceiver 是比较简单的。首先要定义一个类继承 BraodcastReceiver,并且覆盖 onReceiver()方法来响应事件。然后注册在程序 中 BraodcastReceiver。最后构建 Intent 对象调用 sendBroadcast()方法将广播 发出。

    包含静态注册方式和动态注册方式:

  (1)静态注册方式

静态注册方式是在 AndroidManifest.xml 的 application 里面定义 receiver 并设置要接收的 action。静态注册方式的特点:不管改应用程序是否 处于活动状态,都会进行监听,比如某个程序时监听内存的使用情况的,当 在手机上安装好后,不管改应用程序是处于什么状态,都会执行改监听方法中的内容。

  (2)动态注册方式

  在 activity 里面调用函数来注册,和静态的内容差不多。一个形参是 receiver, 另一个是 IntentFilter,其中里面是要接收的 action。动态注册方式特点:在 代码中进行注册后,当应用程序关闭后,就不再进行监听。当然,也可手工调用unregisterReceiver()进行销毁。

  (3)BroadcastReceiver 的生命周期

  一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)的才有效的,当从该函数返回后,该对象就无效的了,结束生命周期。

  (4)Notification

  Notification 可以提供持久的通知,位于手机最上层的状态通知栏中。用手指按下状 态栏,并从手机上方向下滑动,就可以打开状态栏查看提示消息。

  通知一般通过NotificationManager服务发送一个Notification对象来完成通知,NotificationManager是一个重要的系统级服务,该对象位于应用程序的框架层中,应用程序可以通过它向系统发送全局的通知。使用通知的时候,需要创建一个Notification对象用来承载通知的内容,但是一般不会直接通过Notification的构造方法来得到对象,而是使用它的内部类Notification.Builder来实例化一个Builder对象,并设置通知的各项属性,最后通过Notification.Builder.builder()方法得到一个Notification对象,当获得这个Notification对象之后,就可以使用NotificationManager.notify()方法发送通知。

源码下载

源码下载点击这里~

1、本实验实验环境:

操作系统 Windows 10

实验软件 Android Studio 2.2.1

虚拟设备:Nexus_6

API:19(其他高版本的API可能会将提示图表显示成一个白圆点,API19测试可正常显示)

2、贴代码的时候由于插入代码框的大小问题,代码格式不太严整,望见谅~

转载于:https://www.cnblogs.com/yanglh6-jyx/p/Android_Broadcast_Notification_StaticReciver_DynamicReceiver.html

Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式...相关推荐

  1. 简单的入门Android开发和Java语言基础[图]

    简单的入门Android开发和Java语言基础[图] 前言: 去年年底到今年年初,我做过简单的智能家居,也实现过一些简单的直连和远程的智能家居.于是就将最简单的通信发布出来:智能家居简单实现-使用ES ...

  2. Android开发之多线程编程Thread和Runnable使用

    Android开发之多线程编程Thread和Runnable使用 Android可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:前者只要继承了Thread类同时覆写了 ...

  3. 【Android NDK 开发】JNI 动态注册 ( 动态注册流程 | JNI_OnLoad 方法 | JNINativeMethod 结构体 | GetEnv | RegisterNatives )

    文章目录 I . 动态注册流程 ( 总结 ) II . JNI_OnLoad 方法 III . 被注册的本地 C/C++ 方法参数 IV . JNINativeMethod 结构体 ( 核心重点 ) ...

  4. android 函数名注册,Android JNI 函数注册的两种方式(静态注册/动态注册)

    在Android开发中,由于种种原因我们需要调用C/C++代码, 这个时候就要用到Android开发者都听说过的JNI(Java Native Interface)了, 在调用JNI相关方法之前, 要 ...

  5. android的动态注册,Android JNI 函数注册的两种方式(静态注册/动态注册)

    JNI/NDK 在Android开发中,由于种种原因我们需要调用C/C++代码, 这个时候就要用到Android开发者都听说过的JNI(Java Native Interface)了, 在调用JNI相 ...

  6. Android开发(2) | 广播 Broadcast 的应用——强制下线功能

    文章目录 功能简介 关闭所有活动 登陆界面 发送强制下线的广播 广播接收器 AndroidManifest.xml 运行结果 功能简介 强制下线功能只需要弹出一个对话框,让用户只能点击确定按钮,回到登 ...

  7. 〖Web全栈开发①〗—网络编程基础(上)

    网络编程基础 网络编程 网络编程概述 TCP/IP协议 IP地址 什么是IP IP组成 IP 地址使用过程 查看IP Ip地址分类: 子网掩码 端口 socket Socket原理 1.什么是Sock ...

  8. Android开发笔记(一百七十)给App的应用页面注册快捷方式

    元数据不单单能传递简单的字符串参数,还能传送更复杂的资源数据,从Android7.1开始新增的快捷方式便用到了这点,譬如在手机上桌面长按支付宝图标,会弹出如下图所示的菜单. 点击菜单项"扫一 ...

  9. 结合Unity开发中一些编程基础概念与原理性知识总结

     目录: //里氏替换 //抽象类和接口 //虚函数(方法)和抽象方法.普通方法.重载.重写 //指针.引用.值类型.引用类型 //程序.进程.线程.死锁.协程 //内存的几个分区及其作用 //con ...

  10. 深度学习开发环境及编程基础

    1. 独立环境配置 conda 配置一套OS相关工具包(编译好库) 创建环境 conda create -n 环境名 python=3.7 其它conda包 进入环境 conda acitvate 环 ...

最新文章

  1. 几种Windows进程通信
  2. 博客园计划增加的功能
  3. BZOJ 3694DTOJ 1972: 最短路
  4. 反垃圾邮件,需要全面了解各种方案
  5. mysql约束添加删除数据_mysql中约束的添加,修改,与删除
  6. 还要什么ETL?它是搭建数据仓库的必备,许多人都不知道!
  7. delphi 获取桌面路径
  8. android gif转jpg格式文件,android使用多张图片合成gif文件
  9. 【NLP】毕设学习笔记(一):词袋模型、主题模型、词嵌入
  10. 【杂题总结】洛谷-3959 宝藏
  11. RestExpress response中addHeader 导致stackOverflow
  12. leetcode c++未初始化_LeetCode 力扣官方题解 | 538. 把二叉搜索树转换为累加树
  13. 令人纠结的表单设计:水平选项 Or 垂直选项?
  14. windows纯手工安装php和Apache以及连接mysql
  15. vega56刷64_Vega56显卡怎么刷Bios VEGA56显卡刷Vega64方法
  16. java 时分秒转毫秒_运行时间(Java版本)—转换毫秒到时分秒日期
  17. kbhit(), bioskey(), system(pause)
  18. 专业的机器人资讯与太空中的ROS
  19. |PS内置滤镜简介|
  20. web开发 简单的html

热门文章

  1. 制作一个小型linux
  2. Spring AOP的日志记录
  3. AIMS 2013中的性能报告工具不能运行的解决办法
  4. Switch View when host XmlFormView in aspx
  5. 移植marvell poncat3 demo板的总结
  6. insertBefore方法(javascript与jQuery)
  7. ubuntu日常使用指南
  8. table内容保存到Excel中
  9. 关于离散数学的一点事情
  10. Winform--处理MDI父窗体与子窗体的交互