当前位置: 首页 > 编程日记 > 正文

Android组件系列----BroadcastReceiver广播接收器

【声明】

欢迎转载,但请保留文章原始出处→_→

生命壹号:http://www.cnblogs.com/smyhvae/

文章来源:http://www.cnblogs.com/smyhvae/p/3960623.html

 

【正文】

一、广播的功能和特征

  • 广播的生命周期很短,经过调用对象-->实现onReceive-->结束,整个过程就结束了。从实现的复杂度和代码量来看,广播无疑是最迷你的Android 组件,实现往往只需几行代码。广播对象被构造出来后通常只执行BroadcastReceiver.onReceive方法,便结束了其生命周期。所以有的时候我们可以把它当做函数看也未必不可。
  • 和所有组件一样,广播对象也是在应用进程的主线程中被构造,所以广播对象的执行必须是要同步且快速的。也不推荐在里面开子线程,因为往往线程还未结束,广播对象就已经执行完毕被系统销毁。如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成。
  • 每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 当 onReceive() 方法在 10 秒内没有执行完毕, Android 会认为该程序无响应。

二、接收系统广播:

广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能收到该广播,并在内部处理相应的逻辑。注册广播的方式有两种,在代码中注册和在清单文件中注册,前者称为动态注册,后者称为静态注册

1、动态注册监听网络变化:

新建工程文件,首先在MainActivity中定义一个内部类netWorkChangeReceiver,并重写父类的onReceive()方法,这样每当网络状态发生变化时,onReceive()方法就会得到执行,这里使用Toast提示一段文本信息,代码如下:

class netWorkChangeReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();}        }

紧接着在onCreate方法中进行动态注册,然后在onDestroy方法中进行取消注册:

 1     private IntentFilter intentFilter;
 2     private netWorkChangeReceiver netWorkChangeReceiver;
 3     
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.activity_main);
 8         
 9         //动态注册:创建一个IntentFilter的实例,添加网络变化的广播(功能是对组件进行过滤,只获取需要的消息)
10         intentFilter = new IntentFilter();
11         intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
12         //创建NetWorkChangeReceiver的实例,并调用registerReceiver()方法进行注册
13         netWorkChangeReceiver = new netWorkChangeReceiver();
14         registerReceiver(netWorkChangeReceiver, intentFilter);
15         
16     }
17 
18     //取消注册,一定要记得,不然系统会报错
19     @Override
20     protected void onDestroy() {
21         super.onDestroy();
22         unregisterReceiver(netWorkChangeReceiver);
23     }

上方代码解释如下:

11行:给意图过滤器intentFilter添加一个值为android.net.conn.CONNECTIVITY_CHANGE的action。因为每当网络状态发生变化时,系统就会发出一条值为android.net.conn.CONNECTIVITY_CHANG的广播。

注:最后要记得,动态注册的广播接收器一定要取消注册才行

运行程序,就可以了。

不过只是提醒网络发生变化还不够人性化,为了能够准确的告诉用户当前是有网络还是没有网络,我们还需要对上述代码进一步优化,修改netWorkChangeReceiver中的代码如下:

 1     class netWorkChangeReceiver extends BroadcastReceiver {
 2         
 3         @Override
 4         public void onReceive(Context context, Intent intent) {
 5             //通过getSystemService()方法得到connectionManager这个系统服务类,专门用于管理网络连接
 6             ConnectivityManager connectionManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
 7             NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
 8             if(networkInfo != null && networkInfo.isAvailable()){
 9                 Toast.makeText(context, "network is available",Toast.LENGTH_SHORT).show();
10             }else{
11                 Toast.makeText(context, "network is unavailable",Toast.LENGTH_SHORT).show();
12             }
13                 
14         }
15     }

上方代码解释:

06行:在onReceive()方法中,首先通过通过getSystemService()方法得到connectionManager这个系统服务类,专门用于管理网络连接。

07行:然后调用它的getActiveNetworkInfo()方法可以得到NetworkInfo的实例,接着调用NetworkInfo的isAvailable()方法,就可以判断当前是否有网络了,最后通过Toast提示用户。

另外,查询系统的网络状态是需要申明权限的,打开清单文件,添加如下权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

注:访问http://developer.android.com/reference/android/Manifest.permission.html可以查看Android系统所有的可声明的权限。

现在运行程序,就可以了。

上方程序完整版代码如下:

 1 package com.example.m05_broadcastreceiver01;
 2 import android.app.Activity;
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 import android.content.IntentFilter;
 7 import android.net.ConnectivityManager;
 8 import android.net.NetworkInfo;
 9 import android.os.Bundle;
10 import android.widget.Toast;
11 public class MainActivity extends Activity {
12     private IntentFilter intentFilter;
13     private netWorkChangeReceiver netWorkChangeReceiver;
14     @Override
15     protected void onCreate(Bundle savedInstanceState) {
16         super.onCreate(savedInstanceState);
17         setContentView(R.layout.activity_main);
18         // 动态注册:创建一个IntentFilter的实例,添加网络变化的广播
19         intentFilter = new IntentFilter();
20         intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
21         // 创建NetWorkChangeReceiver的实例,并调用registerReceiver()方法进行注册
22         netWorkChangeReceiver = new netWorkChangeReceiver();
23         registerReceiver(netWorkChangeReceiver, intentFilter);
24     }
25     // 取消注册,一定要记得,不然系统会报错
26     @Override
27     protected void onDestroy() {
28         super.onDestroy();
29         unregisterReceiver(netWorkChangeReceiver);
30     }
31     class netWorkChangeReceiver extends BroadcastReceiver {
32         @Override
33         public void onReceive(Context context, Intent intent) {
34             //通过getSystemService()方法得到connectionManager这个系统服务类,专门用于管理网络连接
35             ConnectivityManager connectionManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
36             NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
37             if(networkInfo != null && networkInfo.isAvailable()){
38                 Toast.makeText(context, "network is available",Toast.LENGTH_SHORT).show();
39             }else{
40                 Toast.makeText(context, "network is unavailable",Toast.LENGTH_SHORT).show();
41             }
42                 
43         }
44     }
45 }
View Code

2、静态注册实现开机启动:

动态注册的方式比较灵活,但缺点是:必须在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。为了让程序在未启动的情况下就能接收到广播,这里就需要使用到静态注册

这里我们准备让程序接收一条开机广播,当收到这条广播时,就可以在onReceive()方法中执行相应的逻辑,从而实现开机启动的功能。

新建一个类:BootCompleteReceiver,让他继承BroadcastReceiver,在onReceive()方法中简单地Toast一下,代码如下:

public class BootCompleteReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();}
}

可以看到,这里不再使用内部类的方式来定义广播接收器,因为稍后我们需要在清单文件AndroidManifest.xml中将这个广播接收器的类名注册进去。

然后修改清单文件AndroidManifest.xml,代码如下:

 1 <uses-sdk
 2         android:minSdkVersion="8"
 3         android:targetSdkVersion="16" />
 4     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 5     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
 6 
 7     <application
 8         android:allowBackup="true"
 9         android:icon="@drawable/ic_launcher"
10         android:label="@string/app_name"
11         android:theme="@style/AppTheme" >
12         <activity
13             android:name="com.example.m05_broadcastreceiver01.MainActivity"
14             android:label="@string/app_name" >
15             <intent-filter>
16                 <action android:name="android.intent.action.MAIN" />
17 
18                 <category android:name="android.intent.category.LAUNCHER" />
19             </intent-filter>
20         </activity>
21         
22         <receiver android:name=".BootCompleteReceiver">
23             <intent-filter >
24                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
25             </intent-filter>
26         </receiver>
27     </application>

代码解释如下:

终于,<application>标签内多了个子标签<receiver>,所有的静态注册的广播接收器都是在这里进行注册的。

22行:name中为广播接收器的名字

24行:想要接收的广播。Android系统启动完成后,会发出这条名为android.intent.action.BOOT_COMPLETED的广播。

05行:监听系统开机广播需要声明权限。

运行程序后,将手机关机重启,就能收到这条广播了。

三、发送自定义广播

1、发送标准广播  

新建工程文件。在发广播之前,我们先定义一个广播接收器来接收此广播才行。因此,新建一个类:MyBroadcastReceiver,让他继承BroadcastReceiver,代码如下:

public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();}
}

这里,当MyBroadcastReceiver 收到自定义的广播时,就会执行onReceive()方法中的逻辑,弹出一个Toast。

紧接着,要在清单文件AndroidManifest.xml中对这个广播接收器进行注册:

 1     <application
 2         android:allowBackup="true"
 3         android:icon="@drawable/ic_launcher"
 4         android:label="@string/app_name"
 5         android:theme="@style/AppTheme" >
 6         <activity
 7             android:name="com.example.m05_broadcastreceiver02.MainActivity"
 8             android:label="@string/app_name" >
 9             <intent-filter>
10                 <action android:name="android.intent.action.MAIN" />
11 
12                 <category android:name="android.intent.category.LAUNCHER" />
13             </intent-filter>
14         </activity>
15         
16         <receiver android:name=".MyBroadcastReceiver">
17             <intent-filter >
18                 <action android:name="com.example.m05_broadcastreceiver02.MY_BROADCAST"/>
19             </intent-filter>
20         </receiver>
21     </application>

代码解释:

18行:让MyBroadcastReceiver接收一条值为om.example.m05_broadcastreceiver02.MY_BROADCAST的广播,因此待会儿在发送广播的时候,我们就需要发出这样的一条广播。

紧接着,修改activity.xml中的代码,添加一个按钮Button。

然后,修改MainActivity.java中的代码,添加Button的监听事件:点击按钮时,发送广播

        Button button1=(Button)findViewById(R.id.button1);button1.setOnClickListener(new OnClickListener() {            @Overridepublic void onClick(View v) {
                Intent intent =new Intent("com.example.m05_broadcastreceiver02.MY_BROADCAST");sendBroadcast(intent);}});

总结:可以看到,点击按钮时,发送com.example.m05_broadcastreceiver02.MY_BROADCAST这条广播,这样,所有能够监听com.example.m05_broadcastreceiver02.MY_BROADCAST这条广播的广播接收器就都会同时收到消息,此时发出去的就是一条标准广播,即无序广播。所以接下来就需要讲到有序广播。

2、发送有序广播:

广播是一种可以跨进程的通信方式,其他应用程序是可以收到的。现在我们来发一条有序广播。

有序广播不仅有先后顺序,而且前面的广播还可以将后面的广播截断。

在3.1的代码基础之上,将按钮的监听事件修改如下:

1         Button button1=(Button)findViewById(R.id.button1);
2         button1.setOnClickListener(new OnClickListener() {            
3             @Override
4             public void onClick(View v) {
5                 Intent intent =new Intent("com.example.m05_broadcastreceiver02.MY_BROADCAST");
6                 sendOrderedBroadcast(intent, null);
7             }
8         });

即将06行代码修改一下,将sendBroadcast()方法改为sendOrderedBroadcast()方法,sendOrderedBroadcast()方法接收两个参数,第二个参数是一个与权限相关的字符串,这里传入null即可。

紧接着,修改清单文件AndroidManifest.xml中对广播接收器的注册,设置优先级:

1         <receiver android:name=".MyBroadcastReceiver">
2             <intent-filter android:priority="100">
3                 <action android:name="com.example.m05_broadcastreceiver02.MY_BROADCAST"/>
4             </intent-filter>
5         </receiver>

即添加第02行代码。可以看到,通过android:priority属性给广播接收器设置了优先级。这个属性的范围在-1000到1000,数值越大,优先级越高。

接下来,如果想要拦截这个广播,防止让后面的广播接收器也接收到了这个广播。可以修改MyBroadcastReceiver中的代码:

1 public class MyBroadcastReceiver extends BroadcastReceiver {
2 
3     @Override
4     public void onReceive(Context context, Intent intent) {
5         Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
6         abortBroadcast();//拦截广播,防止后面的接收到
7     }
8 }

即添加第06行代码。如果在onReceive()方法中调用了abortBroadcast()方法,就表示是将这条广播拦截,后面的广播接收器将无法再接收到

特别关注:

  • 广播接收器的生命周期:关键在于BroadcastReceiver中的onReceive()方法,从onReceive()里的第一行代码开始,onReceive()里的最后一行代码结束。
  • 一个广播到来的时候,用什么方式提醒用户是最友好的呢?第一种方式是吐司,第二种方式是通知。注:不要使用对话框,以免中断了用户正在进行的操作。

四、使用本地广播:

之前我们发送和接收的广播全部都是属于全局广播,即发出去的广播可以被其他任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样一来,必然会造成安全问题。于是便有了本地广播:即只能在本应用程序中发送和接收广播。这就要使用到了LocalBroadcastManager这个类来对广播进行管理。

我们修改2.1中动态注册广播接收器的代码,即修改MainActivity.java中的代码如下:

package com.example.broadcasttest;import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;public class MainActivity extends Activity {private IntentFilter intentFilter;private LocalReceiver localReceiver;private LocalBroadcastManager localBroadcastManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//通过LocalBroadcastManager的getInstance()方法得到它的一个实例
        localBroadcastManager = LocalBroadcastManager.getInstance(this);Button button = (Button) findViewById(R.id.button);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");localBroadcastManager.sendBroadcast(intent);//调用sendBroadcast()方法发送广播
            }});//动态注册本地的广播接收器intentFilter = new IntentFilter();intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");localReceiver = new LocalReceiver();localBroadcastManager.registerReceiver(localReceiver, intentFilter);}@Overrideprotected void onDestroy() {super.onDestroy(); localBroadcastManager.unregisterReceiver(localReceiver);}class LocalReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "received local broadcast",Toast.LENGTH_SHORT).show();}}
}

注:本地广播是无法通过静态注册的方式来接收的。其实也完全可以理解,因为静态注册主要就是为了让程序在未启动的情况下也能收到广播。而发送本地广播时,我们的程序肯定是已经启动了,没有必要使用到静态注册的功能。

五、各种各样的广播: 

在android中有很多系统自带的intent.action,通过监听这些事件我们可以完成很多功能。

    1. 开机:
      String BOOT_COMPLETED_ACTION 广播:在系统启动后。这个动作被广播一次(只有一次)。监听: “android.intent.action.BOOT_COMPLETED”
    2. 电话拨入:
      String ANSWER_ACTION 动作:处理拨入的电话。监听: “android.intent.action.ANSWER”
    3. 电量变化:
      String BATTERY_CHANGED_ACTION 广播:充电状态,或者电池的电量发生变化。监听: “android.intent.action.BATTERY_CHANGED”
    4. 日期改变:
      String DATE_CHANGED_ACTION 广播:日期被改变。 监听:“android.intent.action.DATE_CHANGED”
    5. 取消更新下载:
      String FOTA_CANCEL_ACTION 广播:取消所有被挂起的 (pending) 更新下载。 监听:“android.server.checkin.FOTA_CANCEL”
    6. 更新开始安装:
      String FOTA_READY_ACTION 广播:更新已经被下载 可以开始安装。监听 “android.server.checkin.FOTA_READY”
    7. 主屏幕:
      String HOME_CATEGORY 类别:主屏幕 (activity)。设备启动后显示的第一个 activity。 监听:"android.intent.category.HOME”
    8. 新应用:
      String PACKAGE_ADDED_ACTION 广播:设备上新安装了一个应用程序包。监听: “android.intent.action.PACKAGE_ADDED”
    9. 删除应用:
      String PACKAGE_REMOVED_ACTION 广播:设备上删除了一个应用程序包。监听: “android.intent.action.PACKAGE_REMOVED”
    10. 屏幕关闭:
      String SCREEN_OFF_ACTION 广播:屏幕被关闭。监听: “android.intent.action.SCREEN_OFF”
    11. 屏幕开启:
      String SCREEN_ON_ACTION 广播:屏幕已经被打开。 监听:“android.intent.action.SCREEN_ON”
    12. 时区改变:
      String TIMEZONE_CHANGED_ACTION 广播:时区已经改变。监听: “android.intent.action.TIMEZONE_CHANGED”
    13. 时间改变:
      String TIME_CHANGED_ACTION 广播:时间已经改变(重新设置)。 “android.intent.action.TIME_SET”
    14. 时间流逝:
      String TIME_TICK_ACTION 广播:当前时间已经变化(正常的时间流逝)。 “android.intent.action.TIME_TICK”
    15. 进入大容量存储模式:
      String UMS_CONNECTED_ACTION 广播:设备进入 USB 大容量存储模式。 “android.intent.action.UMS_CONNECTED”
    16. 退出大容量存储模式:
      String UMS_DISCONNECTED_ACTION 广播:设备从 USB 大容量存储模式退出。 “android.intent.action.UMS_DISCONNECTED”
    17. 壁纸改变:
      String WALLPAPER_CHANGED_ACTION 广播:系统的墙纸已经改变。 “android.intent.action.WALLPAPER_CHANGED”
    18. web搜索:
      String WEB_SEARCH_ACTION 动作:执行 web 搜索。 “android.intent.action.WEB_SEARCH”
    19. 网络变化:
      String CONNECTIVITY_CHANGE_ACTION 动作:网络变化。“android.intent.action.CONNECTIVITY_CHANGE_ACTION”

六、实例:使用动态注册,监听手机的电量变化

完整版代码如下:

(1)activity_main.xml代码如下:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context=".MainActivity" >
10 
11     <TextView
12         android:id="@+id/textView1"
13         android:layout_width="match_parent"
14         android:layout_height="wrap_content"
15         android:textSize="30dp"
16         android:gravity="center"/>
17 
18 </LinearLayout> 

(2)MainActivity.java的代码如下:

 1 package com.example.m05_broadcastreceiver02;
 2 
 3 import android.app.Activity;
 4 import android.content.BroadcastReceiver;
 5 import android.content.Context;
 6 import android.content.Intent;
 7 import android.content.IntentFilter;
 8 import android.os.Bundle;
 9 import android.widget.TextView;
10 
11 public class MainActivity extends Activity {
12 
13     
14     private BatteryBroadcastReceiver batteryBroadcastReceiver;
15     private TextView textView;
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.activity_main);
20         textView=(TextView)findViewById(R.id.textView1);
21         
22         //动态注册监听电量的广播接收器
23         IntentFilter intentFilter = new IntentFilter();
24         intentFilter.addAction("android.intent.action.BATTERY_CHANGED");
25         batteryBroadcastReceiver = new BatteryBroadcastReceiver();
26         registerReceiver(batteryBroadcastReceiver, intentFilter);       
27     }
28     
29     //取消注册监听电量的广播接收器
30     @Override
31     protected void onDestroy() {
32         super.onDestroy();
33         unregisterReceiver(batteryBroadcastReceiver);
34     }
35 
36     //新建一个广播接收器,监听电量的变化
37     public class BatteryBroadcastReceiver extends BroadcastReceiver {
38         @Override
39         public void onReceive(Context context, Intent intent) {
40             if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
41                 //获取当前电量
42                 int level = intent.getIntExtra("level", 0);
43                 //电量的总刻度
44                 int scale = intent.getIntExtra("scale", 100);
45                 textView.setText("电池电量为"+((level*100) / scale)+"%");
46                 
47                 //当电量低时,可以进行一些操作,例如弹出通知等
48 /*                if(level<15){
49                     do something
50                 }*/
51             }
52         }
53         
54     }
55     
56 }

紧接着,在清单文件中进行权限声明:

<uses-permission android:name="android.permission.BATTERY_STATS"/>

MainActivity.java的代码解释如下:

40至45行:固定代码,用于获取当前电量

48至50行:当电量低时,可以进行一些操作,例如弹出通知等

运行后,界面如下:

相关文章:

Swift 代码调试-善用XCode工具(UI调试,五种断点,预览UIImage...)

原创Blog&#xff0c;转载请注明出处 http://blog.csdn.net/hello_hwc?viewmodelist 我的stackoverflow 工欲善其事&#xff0c;必先利其器&#xff0c;强烈建议新手同学好好研究下XCode这个工具。比如Build Settings&#xff0c;Build Info Rules&#xff0c;Build Parse…

Linux下getopt_long函数的使用

getopt_long为解析命令行参数函数&#xff0c;它是Linux C库函数。使用此函数需要包含系统头文件getopt.h。 getopt_long函数声明如下&#xff1a; int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);…

Expect自动化控制简单介绍

telnet&#xff0c;ftp&#xff0c;Passwd&#xff0c;fsck&#xff0c;rlogin&#xff0c;tip&#xff0c;ssh等等。该工具利用Unix伪终端包装其子进程&#xff0c;允许任意程序通过终端接入进行自动化控制&#xff1b;也可利用Tk工具&#xff0c;将交互程序包装在X11的图形用…

C++中标准模板库std::vector的实现

以下实现了C标准模板库std::vector的部分实现&#xff0c;参考了 cplusplus. 关于C中标准模板库std::vector的介绍和用法可以参考 https://blog.csdn.net/fengbingchun/article/details/51510916 实现代码vector.hpp内容如下&#xff1a; #ifndef FBC_STL_VECTOR_HPP_ #defi…

Swift学习 OOP三大特性:继承、多态、封装

先看个例子 从上面的例子可以总结那么一句话:”学生是人”。也就是Student类继承People类。简而言之&#xff0c;学生是人&#xff0c;这句话是说得通的&#xff0c;但是”人是学生”这句话是说不通的&#xff0c;不是学生就不是人了嘛? 从代码中&#xff0c;我们可以看出S…

5折票倒计时3天 | 超干货议程首度曝光!2019 中国大数据技术大会邀您共赴

&#xff08;大会官网https://t.csdnimg.cn/U1wA&#xff09;2019年&#xff0c;大数据与人工智能的热度已经蔓延到了各个领域&#xff0c;智能交通、AIoT、智慧城市&#xff0c;智慧物流、AI中台、工业制造等各种黑科技成为热搜名词。而在今年的乌镇互联网大会上&#xff0c;大…

mysql select * f

mysql> select * from tb;-------------| id | name |-------------| 1 | tbone || 3 | 2d2 || 5 | 55 || 6 | 66 |-------------4 rows in set (0.00 sec)转载于:https://www.cnblogs.com/bashala/p/3974088.html

C++/C++11中用于定义类型别名的两种方法:typedef和using

类型别名(type alias)是一个名字&#xff0c;它是某种类型的同义词。使用类型别名有很多好处&#xff0c;它让复杂的类型名字变得简单明了、易于理解和使用&#xff0c;还有助于程序员清楚地知道使用该类型的真实目的。在C中&#xff0c;任何有效类型都可以有别名。 有两种方法…

iOS学习笔记--01swift实现提示框第三方库:MBProgressHUD

本文使用swift语言使用MBProgressHUD。 开源项目MBProgressHUD可以实现多种形式的提示框。使用简单&#xff0c;方便。GitHud的下载地址是&#xff1a;https://github.com/jdg/MBProgressHUD/ 下载完成后&#xff0c;将MBProgressHUD.h和MBProgressHUD.m拖入已经新建好的Swift项…

2019北京智源大会在京开幕, 中外学术大咖共话人工智能研究前沿

10月31日&#xff0c;由北京智源人工智能研究院主办的2019北京智源大会在国家会议中心开幕&#xff0c;会期两天。智源大会是北京创建全球人工智能学术和创新最优生态的标志性学术活动&#xff0c;定位于“内行的AI盛会”&#xff0c;以国际性、权威性、专业性和前瞻性为特色&a…

linux中登录类型及配置文件

linux中登录shell的类型1.交互式登录&#xff1a;直接通过终端输入用户信息登录1&#xff09;login&#xff1a;2&#xff09;在shell中 su - usernamesu -l username2.非交互式登录1&#xff09;su username2&#xff09;图形界面的终端3&#xff09;执行脚本的过程用户配置文…

Swift项目引入第三方库的方法

分类&#xff1a;iOS&#xff08;55&#xff09; 目录(?)[] Swift项目引入第三方库的方法 转自 http://blog.shiqichan.com/How-To-Import-3rd-Lib-Into-Swift-Project/ 以下&#xff0c;将创建一个Swift项目&#xff0c;然后引入3个库&#xff1a; Snappy 简化autolayout代码…

最新NLP架构的直观解释:多任务学习– ERNIE 2.0(附链接)| CSDN博文精选

作者 | Michael Ye翻译 | 陈雨琳&#xff0c;校对 | 吴金笛来源 | 数据派THU&#xff08;ID&#xff1a;DatapiTHU&#xff09;百度于今年早些时候发布了其最新的NLP架构ERNIE 2.0&#xff0c;在GLUE基准测试中的所有任务上得分均远高于XLNet和BERT。NLP的这一重大突破利用了一…

C++中的内存对齐介绍

网上有很多介绍字节对齐或数据对齐或内存对齐的文章&#xff0c;虽然名字不一样&#xff0c;但是介绍的内容大致都是相同的。这里以内存对齐相称。注&#xff1a;以下内容主要来自网络。 内存对齐&#xff0c;通常也称为数据对齐&#xff0c;是计算机对数据类型合法地址做出了…

__cplusplus的用处

经常在/usr/include目录下看到这种字句&#xff1a; #ifdef __cplusplus extern "C" { #endif ... #ifdef __cplusplus } #endif 不太明白是怎么用的。今天阅读autobook&#xff0c;在第53页看到了作者的解释&#xff1a;C/C编译器对函数和变量名的命名方法不一样…

Linux下的内存对齐函数

在Linux下内存对齐的函数包括posix_memalign, aligned_alloc, memalign, valloc, pvalloc&#xff0c;其各个函数的声明如下&#xff1a; int posix_memalign(void **memptr, size_t alignment, size_t size); void *memalign(size_t alignment, size_t size); void *aligned_…

Swift2.0系列]Error Handling(项目应用篇)

1.FileManager中的应用 倘若你只是想看FileManager中的 Error Handling是如何实现的&#xff0c;请找到3.删除文件以及4.获取文件信息。我分别为你提供了do-catch以及try?的使用方法。 打开Xcode,选中Single View Application&#xff0c;输入项目名称例如FileManagerDemo,点击…

总点第一个视频产生选择偏差?Youtube用“浅塔”来纠正

作者 | Tim Elfrink译者 | Tianyu出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】本文来自于谷歌研究人员最近发表的一篇论文&#xff0c;介绍了视频平台 Youtube 的视频推荐方法&#xff0c;并在 RecSys 2019 大会上做了分享。本文总结归纳了一些论文中的重…

HTML样式offset[Direction] 和 style.[direction]的区别

为什么80%的码农都做不了架构师&#xff1f;>>> 以offsetLeft与style.left为例&#xff1a; offsetLeft使用的值是字符串&#xff0c;如“100px", style.left则使用数值&#xff0c;如 100 offsetLeft只可以读&#xff0c;因此用无法通过Js改变这个值实现样…

Ubuntu 14.04上安装pip3/numpy/matplotlib/scipy操作步骤

Ubuntu 14.04 64位上默认安装了两个版本的python&#xff0c;一个是python2.7.6,另外一个是python3.4.0&#xff0c;如下图所示&#xff1a; 安装完pip3的结果如下图所示&#xff1a; 升级完pip3的结果如下图所示: 安装完numpy的结果如下图所示: 通过sudo pip3 install matplot…

NSHelper.showAlertTitle的两种用法 swift

var model : CarCity CarCity() if (NSString.isNullOrEmpty(locationLabel.text)) { NSHelper.showAlertTitle(nil, message: "暂无法定位&#xff0c;请检查网络。", cancel: "确定") return } if (NSString.isNullOrEmpty(plateTextFild.text)) { NSHe…

通俗易懂:图卷积神经网络入门详解

作者 | 蝈蝈来源 | 转载自知乎用户蝈蝈【导读】GCN问世已经有几年了&#xff08;2016年就诞生了&#xff09;&#xff0c;但是这两年尤为火爆。本人愚钝&#xff0c;一直没能搞懂这个GCN为何物&#xff0c;最开始是看清华写的一篇三四十页的综述&#xff0c;读了几页就没读了&a…

Java数据结构一 —— Java Collections API中的表

1.Collection接口 位于java.util包中&#xff0c;以下是重要的部分。 1 public interface Collection<AnyType> extends Iterable<AnyType> 2 { 3 int size(); 4 boolean isEmpty(); 5 void clear(); 6 boolean add(AnyType x); 7 …

Swift 中的内存管理详解

这篇文章是在阅读《The Swift Programming Language》Automatic Reference Counting&#xff08;ARC&#xff0c;自动引用计数&#xff09;一章时做的一些笔记&#xff0c;同时参考了其他的一些资料。 在早期的 iOS 开发中&#xff0c;内存管理是由开发者手动来完成的。因为传统…

Ubuntu14.04 64位机上配置OpenCV3.4.2+OpenCV_Contrib3.4.2+Python3.4.3操作步骤

Ubuntu 14.04 64位上默认安装了两个版本的python&#xff0c;一个是python2.7.6,另外一个是python3.4.3。这里使用OpenCV最新的稳定版本3.4.2在Ubuntu上安装python3.4.3支持OpenCV的操作步骤如下&#xff1a; 1. 更新包&#xff0c;执行&#xff1a; sudo apt-get update sud…

“Python之父”从Dropbox退休

作者 | 若名出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;10 月 30 日&#xff0c;Python 之父 Guido Van Rossum 宣布将从工作六年的 Dropbox 公司退休&#xff0c;他在 Twitter 上转发了 Dropbox 团队写的《Thank you, Guido》公开信长文。Guido 表示&#xff0c…

谭浩强《C++程序设计》书后习题 第十三章-第十四章

2019独角兽企业重金招聘Python工程师标准>>> 最近要复习一下C和C的基础知识&#xff0c;于是计划把之前学过的谭浩强的《C程序设计》和《C程序设计》习题重新做一遍。 编译环境为&#xff1a;操作系统32位Win7&#xff0c;编译工具VC6.0 第十三章&#xff1a;输入输…

图像处理库(fbc_cv):源自OpenCV代码提取

在实际项目中会经常用到一些基本的图像处理操作&#xff0c;而且经常拿OpenCV进行结果对比&#xff0c;因此这里从OpenCV中提取了一些代码组织成fbc_cv库。项目fbc_cv所有的代码已放到GitHub中&#xff0c;地址为 https://github.com/fengbingchun/OpenCV_Test &#xff0c;它…

Swift2.x编写NavigationController动态缩放titleView

这两天看到一篇文章iOS 关于navigationBar的一些..中的动态缩放比较有意思,看了一下源码,然后用Swift写了一下,使用storyboard实现. 效果图: 部分代码: 设置滑动代理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26/**设置滑动代理- parameter scrollV…

云厂商和开源厂商“鹬蚌相争”,他却看到了开发者的新机会

作者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】过去一年&#xff0c;开发者生态发生了一些或巨大、或微妙的变化&#xff0c;大的变化如巨头云厂商正在通过开源、收购等方式争夺开发者生态&#xff0c;比如微软以 75 亿美金收购 GitHub&#xff…