Android中的广播Broadcast详解

今天来看一下Android中的广播机制,我们知道广播Broadcast是Android中的四大组件之一,可见他的重要性了,当然它的用途也很大的,比如一些系统的广播:电量低、开机、锁屏等一些操作都会发送一个广播,具体的Android系统中的广播可以参见我的另外一篇博客:http://blog.csdn.net/jiangwei0910410003/article/details/17218985.

下面就来详细讲解一下广播机制:

广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。普通广播是完全异步的,可以在同一时刻(逻辑上)被所有广播接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;然而有序广播是按照接收者声明的优先级别(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-10001000。也可以调用IntentFilter对象的setPriority()进行设置),被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给CA得到广播后,可以往广播里存入数据,当广播传给B,B可以从广播中得到A存入的数据。

Context.sendBroadcast()

   发送的是普通广播,所有订阅者都有机会获得并进行处理。

Context.sendOrderedBroadcast()

   发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将处理结果存放进广播Intent,然后传给下一个接收者。


广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者类似。要实现一个广播接收者方法如下:

第一步:定义广播接收者,继承BroadcastReceiver,并重写onReceive()方法。

public class IncomingSMSReceiver extendsBroadcastReceiver {@Override public void onReceive(Contextcontext, Intentintent) {}
}

第二步:订阅感兴趣的广播Intent,订阅方法有两种:

第一种:使用代码进行订阅(动态订阅)

IntentFilter filter = newIntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = newIncomingSMSReceiver();
registerReceiver(receiver, filter);

第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅(静态订阅)

<receiver android:name=".IncomingSMSReceiver"><intent-filter><action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter>
</receiver>


下面看一下动态广播订阅和静态广播订阅的却别:

静态订阅广播又叫:常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接受到,他的注册方式就是在你的应用程序中的AndroidManifast.xml进行订阅的。

动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,比如你在activity中的onCreate或者onResume中订阅广播,同时你必须在onDestory或者onPause中取消广播订阅。不然会报异常,这样你的广播接收器就一个非常驻型的了。

这里面还有一个细节那就是这两种订阅方式,在发送广播的时候需要注意的是:动态注册的时候使用的是隐式intent方式的,所以在发送广播的时候需要使用隐式Intent去发送,不然是广播接收者是接收不到广播的,这一点要注意。但是静态订阅的时候,因为在AndroidMainfest.xml中订阅的,所以在发送广播的时候使用显示Intent和隐式Intent都可以(当然这个只针对于我们自己定义的广播接收者),所以以防万一,我们一般都采用隐式Intent去发送广播。


下面看一下例子:

看一下项目结构:


看一下静态订阅广播:

package com.broadcast.demo;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;import com.example.androidbroadcastdemo.R;/*** 静态订阅广播* @author weijiang204321**/
public class StaticRegisterBroadcastActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button btn = (Button)findViewById(R.id.btn);btn.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {//使用静态的方式注册广播,可以使用显示意图进行发送广播Intent broadcast = new Intent("com.broadcast.set.broadcast");sendBroadcast(broadcast,null);}});}}


在AndroidMainfest.xml中订阅:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.androidbroadcastdemo"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="18" /><!-- 权限 --><uses-permission android:name="android.permission.RECEIVE_SMS"/><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.SEND_SMS"/><uses-permission android:name="android.permission.READ_PHONE_STATE" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="com.broadcast.demo.StaticRegisterBroadcastActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><!-- 无序广播注册START  --><receiver android:name="com.broadcast.receiver.UnSortBroadcastReceiver"><intent-filter ><action android:name="com.broadcast.demo.mybroadcast"/></intent-filter></receiver><!-- 无序广播注册END --><!-- 有序广播的注册START --><receiver android:name="com.broadcast.receiver.SortBroadcastReceiverA"><intent-filter android:priority="999"><action android:name="com.broadcast.set.broadcast"/></intent-filter></receiver><!-- 接收短信广播 --><receiver android:name="com.broadcast.receiver.SortBroadcastReceiverB"><intent-filter android:priority="1000"><action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter></receiver><!-- 有序广播的注册END --><!-- 上传短信内容的Service --><service android:name="com.broadcast.service.UploadSMSService"><intent-filter ><action android:name="com.broadcast.service.uploadsmsservice"/></intent-filter></service></application></manifest>

先不要管其他的内容了,后面会讲到,这里只关注静态广播的注册

<!-- 无序广播注册START  --><receiver android:name="com.broadcast.receiver.UnSortBroadcastReceiver"><intent-filter ><action android:name="com.broadcast.demo.mybroadcast"/></intent-filter></receiver>
<!-- 无序广播注册END -->


下面来看一下广播的接收者:

package com.broadcast.receiver;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;/*** 广播接收者* @author weijiang204321**/
public class UnSortBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Log.e("Intent_Action:",intent.getAction()+"");}}
在广播接收者中的onReceive方法中的逻辑很简单,就是打印Action的内容。

运行程序,结果很简单,这里就不上图片了。


下面来看一下动态订阅:

package com.broadcast.demo;import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;import com.broadcast.receiver.UnSortBroadcastReceiver;
import com.example.androidbroadcastdemo.R;/*** 使用动态的方式注册广播* @author weijiang204321**/
public class DynamicRegisterBroadcastActivity extends Activity {public static final String NEW_LIFEFORM_DETECTED = "com.dxz.broadcasttest.NEW_LIFEFORM";protected  UnSortBroadcastReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button btn0 = (Button) findViewById(R.id.btn);btn0.setOnClickListener(new OnClickListener() {public void onClick(View v) {//发送广播Intent it = new Intent(NEW_LIFEFORM_DETECTED);sendBroadcast(it);}});}@Overrideprotected void onResume() {super.onResume();//注册广播IntentFilter counterActionFilter = new IntentFilter(NEW_LIFEFORM_DETECTED);receiver = new UnSortBroadcastReceiver();registerReceiver(receiver, counterActionFilter);}@Overrideprotected void onPause() {super.onPause();//取消广播unregisterReceiver(receiver);}
}
这里我们是在onResume中进行订阅广播,在onPause中取消订阅广播。

AndroidMainfest.xml中将启动的Activity改成DynamicRegisterBroadcastActivity,其他的内容不需要修改,运行程序,打印结果很简单,这里就不上图了。


下面来看一下有序广播和无序广播

这个我们在开始的时候已经说到了,下面来看一下无序广播:

首先我们定义两个广播接收者:

第一个广播接收者:

package com.broadcast.receiver;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;/*** 广播接收者A* @author weijiang204321**/
public class SortBroadcastReceiverA extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Log.e("Demo:","广播接收者A");}}
第二个广播接收者:

package com.broadcast.receiver;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;/*** 广播接收者B* @author weijiang204321**/
public class SortBroadcastReceiverB extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Log.e("Demo:","广播B");}}


在AndroidMainfest.xml中订阅广播

 <receiver android:name="com.broadcast.receiver.SortBroadcastReceiverA"><intent-filter android:priority="999"><action android:name="com.broadcast.set.broadcast"/></intent-filter>
</receiver><receiver android:name="com.broadcast.receiver.SortBroadcastReceiverB"><intent-filter android:priority="1000"><action android:name="com.broadcast.set.broadcast"/></intent-filter>
</receiver>
运行结果:


运行结果有点奇怪,为什么是接收者B在前面,接收者A在后面,原因就是我们在AndroidMainfest.xml中订阅广播的时候在intent-filter设置了android:priority属性值,值越大优先级越高,接收者B的优先级是1000,接收者A的优先级是999,所以是B先接收到广播,然后A才接收到,但是接收者B和接收者A之间没有联系,也不能有交互的,因为是这是无序广播,是异步的,我们可以做个试验就是在B中的onReceiver方法中添加代码:

abortBroadcast();//终止此次广播的传输

运行结果:


我们可以看到提示错误,就是non-ordered broadcast无序广播不允许终止广播,其实终止也没有用,因为接收者A还是接收到广播了。


下面来看一下有序广播,代码需要做一下修改:

首先是在发送广播的时候:

Intent broadcast = new Intent("com.broadcast.set.broadcast");
sendOrderedBroadcast(broadcast,null);
然后在B接收者中的添加终止广播的方法:

abortBroadcast();

其他的代码不需要修改,运行结果:


只有B接收者了,A接收者没有接收到广播了,因为在B接收者中将广播给终止了,后面的接收者都接受不到了。

下面在修改一下代码:

接收者B:

package com.broadcast.receiver;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;/*** 广播接收者B* @author weijiang204321**/
public class SortBroadcastReceiverB extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Log.e("Demo:","广播接收者B");Bundle bundle = new Bundle();bundle.putString("next_receiver", "下一个广播接收者");setResultExtras(bundle);}}
B接收到广播后,存入一些值,传给下一个接收者。


接收者A的代码:

package com.broadcast.receiver;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;/*** 广播接收者A* @author weijiang204321**/
public class SortBroadcastReceiverA extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Log.e("Demo:","广播接收者A");Bundle bundle = getResultExtras(true);String content = bundle.getString("next_receiver");Log.e("Demo:",content+"");}}
运行结果如下:


接收者A收到了上一个接收者B传递的信息,这个信息可以保留到后面的所有接收者,直到广播终止。

上面讲到的就是有序广播的特点,可以看出是一个同步的动作,接收者之间可以进行数据的交互(上一个传递数据给下一个),也可以控制广播的终止。


下面来做一个案例就是网上很多人弄过的:短信拦截

系统在收到短信的时候,会发送一个:android.provider.Telephony.SMS_RECEIVED这样的广播,而且这是一个有序的广播,所以我们就可以拦截了这条短信,因为系统中的短信接收者的订阅优先级不是1000最高的,所以我们可以自己定义一个短信接收者,将订阅优先级设置成1000,这样我们就可以最先获取到短信内容,然后将截取到知道号码的短信内容上传到服务器上进行保存,然后终止广播。让系统接收不到这条短信。

这里面我们还需要了解的技术就是短信内容的获取,这个我们在代码中解释:

下面来看一下我们定义的短信接收者:

package com.broadcast.receiver;import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;
import com.broadcast.service.UploadSMSService;/*** 广播接收者A* @author weijiang204321**/
public class SortBroadcastReceiverA extends BroadcastReceiver{@SuppressLint("SimpleDateFormat")@Overridepublic void onReceive(Context context, Intent intent) {//获取短信的相关信息,使用字段pdusObject[] pdus = (Object[]) intent.getExtras().get("pdus");StringBuilder content = new StringBuilder();String receiveTime = "";String senderNumber = "";for(Object p : pdus){byte[] pdu = (byte[]) p;SmsMessage message = SmsMessage.createFromPdu(pdu);content.append(message.getMessageBody());Date date = new Date(message.getTimestampMillis());SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");receiveTime = format.format(date);senderNumber = message.getOriginatingAddress();}Log.e("Demo:","上传短信内容是:"+content.toString());Log.e("Demo:","接收短信的时间是"+receiveTime);Log.e("Demo:","发送短信的号码是:"+senderNumber);//拦截的号码是:18910958627,注意前面还有+86是中国地区的编号if("+8618910958627".equals(senderNumber)){//拦截成功 ,上传信息Intent service = new Intent(context,UploadSMSService.class);service.putExtra("content", content.toString());service.putExtra("receiveTime",receiveTime);service.putExtra("senderNumber", senderNumber);context.startService(service);}}}
在onReceive方法中我们通过intent中的Bundle获取短信的相关信息。

下面在看一下上传短信信息的服务Service:

package com.broadcast.service;import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;import android.app.Service;
import android.content.Intent;
import android.os.IBinder;/*** 上传短信内容的service* @author weijiang204321**/
public class UploadSMSService extends Service{@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//获取短信内容和接收时间,发送者的号码final String content = intent.getStringExtra("content");final String receiveTime = intent.getStringExtra("receiveTime");final String senderNumber = intent.getStringExtra("senderNumber");new Thread(){@Overridepublic void run(){sendSMS(content,receiveTime,senderNumber);//上传完成之后就结束servicestopSelf();}}.start();return super.onStartCommand(intent, flags, startId);}/*** 上传短信内容* @param content* @param receiveTime* @param senderNumber* @return*/private boolean sendSMS(String content, String receiveTime, String senderNumber) {try{String params = "content="+ URLEncoder.encode(content, "UTF-8")+"&receivetime="+ receiveTime+ "&sendernumber="+ senderNumber;byte[] entity = params.getBytes();String path = "http://10.2.86.33:8080/ReceiveSMSContent/ReceiveSMSServlet";HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("POST");conn.setDoOutput(true);conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");conn.setRequestProperty("Content-Length", String.valueOf(entity.length));conn.getOutputStream().write(entity);if(conn.getResponseCode() == 200){return true;}}catch (Exception e) {e.printStackTrace();}return false;}}
这个服务的逻辑也很简单的,在获取到短信信息的时候,将内容进行上传。

最后不能忘了在AndroidMainfest.xml中添加权限:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.INTERNET"/>
订阅短信广播:

<receiver android:name="com.broadcast.receiver.SortBroadcastReceiverA"><intent-filter android:priority="999"><action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter>
</receiver>

当然这里还需要有一个短信内容的接收服务端,在服务端定义一个Servlet来接受数据,具体的服务端的环境搭建,自己上网搜索相关资料进行搭建:

package com.servlet.receivesms;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class ReceiveSMSServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {req.setCharacterEncoding("utf-8");String content = req.getParameter("content");String receiveTime = req.getParameter("receivetime");String phoneNumber = req.getParameter("sendernumber");System.out.println("发送内容:"+content);System.out.println("发送时间:"+receiveTime);System.out.println("发送号码:"+phoneNumber);super.doGet(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {super.doPost(req, resp);}}
测试结果,客户端拦截的号码是18910958627,注意前面有+86是中国区域的编码,服务端接收数据为:


这样就表示截取短信内容成功,并且成功上传到服务器上了。


对于上面的短信拦截的功能还有待加强,就是现在想把短信的内容拦截下来,进行篡改,然后再发给下一个接收者?

方案一:在我们定义的短信广播接收者中,我们能够从intent中的Bundle中通过key="pdus"来获取短信内容的,那么我们可以自己从新组建一个新的Bundle,在这个Bundle中存入我们篡改的信息,然后替换之前的Bundle

问题:实施了,但是问题是Bundle是替换不了的,不知道是什么原因?


方案二:由于第一种方案的失败,导致了我从新想到一个方案就是截取短信内容之后,终止此次广播,然后发送一条短信,这时候短信的内容为我们篡改的内容,但是这里需要注意的是,要做判断,因为我们定义的短信接收者的优先级最高,所以我们发送篡改后的短信又被我们的短信接收者给拦截了,但是我们是不想这样的,所以要做个判断,这个很简单的,使用SharePerenced存入一个boolean值就行了。

问题:本来以为这种方案是完美了,但是问题是发送信息的时候,系统提供的方法中的参数是:接收者号码,发送者号码,短信内容,还有其他的参数就不解释了,这很简单呀,我们现在正好需要这三个参数,立马传递进去,结果是收取不到短信,查看文档,发现那个发送者号码的参数是短信服务中心的号码(也不知道什么意思),当把它设置成null的时候短信就可以发出去了,但是设置成null的话,就不能说是谁发的短信了没有意义呀!


现在很纠结,问题还没有解决,如果有哪位大神有好的方法,请说明,小弟不慎感激!


总结:

在Android中,程序的响应(Responsive)被活动管理器(ActivityManager)和窗口管理器(Window Manager)这两个系统服务所监视。当BroadcastReceiver在10秒内没有执行完毕,Android会认为该程序无响应。所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR(Application No Response)的对话框。如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成。而不是使用子线程的方法来解决,因为BroadcastReceiver的生命周期很短(在onReceive()执行后BroadcastReceiver 的实例就会被销毁),子线程可能还没有结束BroadcastReceiver就先结束了。如果BroadcastReceiver结束了,它的宿主进程还在运行,那么子线程还会继续执行。但宿主进程此时很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。

public class IncomingSMSReceiver extendsBroadcastReceiver {@Override public void onReceive(Contextcontext, Intentintent) {//发送Intent启动服务,由服务来完成比较耗时的操作Intent service =new Intent(context,XxxService.class);context.startService(service);}
}

每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法。

所以上面的短信内容上传到服务器上的逻辑功能不能在广播中执行,需要开启一个服务进行上传。



转载于:https://www.cnblogs.com/roccheung/p/5797391.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377315.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sql check约束_在SQL中使用CHECK约束

sql check约束Basically, CHECK constraint is used to LIMIT in columns for the range of values. We can use this constraint for single or multiple columns. 基本上&#xff0c; CHECK约束用于限制值范围内的列 。 我们可以将此约束用于单列或多列。 In single column,…

.NET线程池

摘要 深度探索 Microsoft .NET提供的线程池&#xff0c; 揭示什么情况下你需要用线程池以及 .NET框架下的线程池是如何实现的&#xff0c;并告诉你如何去使用线程池。 内容 介绍 .NET中的线程池 线程池中执行的函数 使用定时器 同步对象的执行 异步I/O操作 监视线程池 死锁 有关…

折线分割平面

Input输入数据的第一行是一个整数C,表示测试实例的个数&#xff0c;然后是C 行数据&#xff0c;每行包含一个整数n(0<n<10000),表示折线的数量。Output对于每个测试实例&#xff0c;请输出平面的最大分割数&#xff0c;每个实例的输出占一行。Sample Input2 1 2Sample Ou…

《c++特性》

目录多态构造函数和析构函数存在多态吗&#xff1f;虚函数表虚析构函数纯虚函数和抽象类运行时多态和编译时多态的区别继承设计实例指针对象和普通对象的区别正确初始化派生类方式继承和赋值的兼容规则protected 和 private 继承基类与派生类的指针强制转换如何用C实现C的三大特…

Scala中的while循环

在Scala中的while循环 (while loop in Scala) while loop in Scala is used to run a block of code multiple numbers of time. The number of executions is defined by an entry condition. If this condition is TRUE the code will run otherwise it will not run. Scala中…

Linux操作系统启动过程

在做开发的过程中&#xff0c;突然发现&#xff0c;要对系统做一些有意义的改变&#xff0c;必须要对操作系统的启动过程有一定的了解&#xff0c;不然就是修改你都不知道从哪里下手啊&#xff0c;然后就是找来资料看&#xff0c;去网上看别人的博客&#xff0c;有了前一周一些…

方法命名的区别

GetDecimalFromString ExtractDecimal 这2个方法名那个比较好呢。上边的明显的是中式英语&#xff0c;单词拼凑而成的。下边的更加流畅一些。方法名称取名还是很有要求的。要通俗易懂还要符合文法。从上边的可以扩展出什么想法呢。 ExtractDecimalExtractDoubleExtractInt16Ext…

工作排序问题

Problem statement: 问题陈述&#xff1a; Given an array of jobs where every job has a deadline and a profit. Profit can be earned only if the job is finished before the deadline. It is also given that every job takes a single unit of time, so the minimum p…

牛客网与leetcode刷题(高频题中简单or中等的)

目录1、反转链表2、排序3、先序中序后序遍历4、最小的k个数5、子数组的最大累加和6、 用两个栈实现队列7、142. 环形链表 II8、20. 有效的括号9、最长公共子串(动态规划),磕磕绊绊10、二叉树之字形层序遍历11、重建二叉树12、LRU缓存13、合并两个有序链表15、大数加法16、一个二…

AMUL的完整形式是什么?

AMUL&#xff1a;阿南德牛奶联盟有限公司 (AMUL: Anand Milk Union Limited) AMUL is an abbreviation of Anand Milk Union Limited. It is an Indian milk product cooperative dairy organization that is based in the small town of Anand in the state of Gujarat. AMUL …

mochiweb 源码阅读(十一)

大家好&#xff0c;今天周六&#xff0c;继续接着上一篇&#xff0c;跟大家分享mochiweb源码。上一篇&#xff0c;最后我们看到了mochiweb_socket_server:listen/3函数&#xff1a; listen(Port, Opts, State#mochiweb_socket_server{sslSsl, ssl_optsSslOpts}) ->case moch…

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能 (转)

转载请注明出处&#xff1a;http://blog.csdn.net/guolin_blog/article/details/9255575 最 近项目中需要用到ListView下拉刷新的功能&#xff0c;一开始想图省事&#xff0c;在网上直接找一个现成的&#xff0c;可是尝试了网上多个版本的下拉刷新之后发现效果都不怎么理 想。有…

Python中的append()和extend()

列出append()方法 (List append() method) append() method is used to insert an element or a list object to the list and length of the List increased by the 1. append()方法用于将元素或列表对象插入列表&#xff0c;并且列表长度增加1。 Syntax: 句法&#xff1a; …

红黑树的实现

目录1、红黑树原理1、红黑树性质2、变换规则&#xff08;从插入结点的角度来讲&#xff09;1.变色2.左旋3.右旋3、删除结点需要注意的地方2、代码1、定义结点以及构造函数2、定义红黑树类以及声明它的方法3、左旋4、右旋5、插入操作6、修正操作7、删除操作3、参考链接1、红黑树…

118 - ZOJ Monthly, July 2012

http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId339 都是赛后做的。。。弱爆了 A题是找由2和5组成的数字的个数 直接打个表就行了 只是比赛的时候不知道怎么打表啊。。 View Code #include<cstdio> #include<cstring> #include<algorith…

edp1.2和edp1.4_EDP​​的完整形式是什么?

edp1.2和edp1.4EDP​​&#xff1a;电子数据处理 (EDP: Electronic Data Processing) EDP is an abbreviation of Electronic Data Processing. It alludes to the functioning of operations of commercial data, documents processing of storing, with the use of a compute…

高效读书心得

1.尽量阅读中文版 虽然有人英文很强&#xff0c;有的翻译很差&#xff0c;但AnyWay 中文阅读与理解的时间&#xff0c;略读与快速定位感兴趣内容的速度还是要快一些。 2.即时批注、总结笔记与交流 虽然爱书&#xff0c;但发现最有效的读书方式还是不断的制造脂批本&…

《MySQL——增删改查以及常用语法》

目录登录和退出MySQL服务器基本语法&#xff08;增删改查&#xff09;登录和退出MySQL服务器 # 登录MySQL 密码 $ mysql -u root -p12345612 # 退出MySQL数据库服务器 exit;基本语法&#xff08;增删改查&#xff09; -- 显示所有数据库 show databases;-- 创建数据库 CREA…

WCF简介

一、简介 WCF是Windows Communication Foundation缩写&#xff0c;是Microsoft为构建面向服务的应用提供的分布式通信编程框架&#xff0c;是.NET Framework 3.5的重要组成部分。使用该框架&#xff0c;开发人员可以构建跨平台、安全、可靠和支持事务处理的企业级互联应用解决方…

css链接样式_CSS中的样式链接

css链接样式CSS样式链接 (CSS Styling Links) The links in CSS can be styled in various ways to make our website more presentable and attractive. The links can also be styled depending on their states e.g. visited, active, hover, etc. CSS中的链接可以通过各种方…