安卓第十三天笔记-服务(Service)
安卓第十三天笔记-服务(Service)
Servcie服务
1.服务概念
服务
- windows
服务没有界面,一直运行在后台, 运行在独立的一个进程里面
- android
服务没有界面,一直运行在后台,默认是运行当前的应用程序进程里面。
2.建立服务
建立一个类继承Service类
public class ServiceDemo extends Service {
在清单文件中注册service
<service android:name="com.ithiema.servicequick.servcie.ServiceDemo"></service>
3.生命周期
只会在开启服务时初始化一次
@Override
public void onCreate() {
//只会在开启服务时初始化一次
super.onCreate();
}
每次开启服务都会执行调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//每次开启服务都会执行调用
return super.onStartCommand(intent, flags, startId);
}
停止服务时,只执行一次
public void onDestroy() {
//停止服务时,只执行一次
super.onDestroy();
}
- 完整生命周期
onCreate -- onStartCommand--onDestroy
- 启动多次服务
onCreate方法只会执行一次, 但是onStartCommand执行多次
- 多次停止服务
只会执行一次onDestroy方法。
4.进程
Foreground process
前台进程: 当前与用户进行交互的应用所处的进程
- Visible process
可见进程: 应用程序不能交互,但是界面可见。 有点类似activity生命周期的onPause
- Service process
服务进程: 应用程序里面运行着一个服务
- Background process
后台进程: 应用程序被最小化了(home)
- Empty process
空进程:应用程序里面没有任何活动的组件(activity \ service)
前台进程 > 可见进程 > 服务进程 > 后台进程 > 空进程
5.开启与停止服务
public void start(View v){
startService(new Intent(this , ServiceDemo.class));
}
public void stop(View v){
stopService(new Intent(this , ServiceDemo.class));
}
6.为什么要使用服务
- 可以让进程所处的优先级有所保障。
- 可以长久的在后台执行逻辑操作,即使所有的activity都销毁了,也不影响。
场景: 1. 在后台检测设备接入状况 2. 在后台执行联网数据请求(类似股票软件) 3. 音乐播放器
7.绑定服务第一种
Extending the Binder class 第一种
1 先写一个继承Service类
2.在Service中写一个public类继承Binder,在这个类中写个方法返回具服务类的对象实例
3.在onBind 中返回 这个内部类的实例
4.在service中写几个public的方法提供给子类调用必须为public的
/**
* Created by 刘楠 on 2016-02-28 14:19.
*/
public class LocalService extends Service {
private static final String TAG = "LocalService";
//声明绑定的类
private LocalBinder mBinder = new LocalBinder();
//给客户端使用
private final Random mGenerator = new Random(); /*
第一种继承Binder类
*/
public class LocalBinder extends Binder { public LocalService getServcie() {
Log.d(TAG, "==getServcie==");
return LocalService.this;
} } @Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "==IBinder==");
return mBinder;
} @Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "==onCreate==");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "==onStartCommand==");
return super.onStartCommand(intent, flags, startId);
} /**
* 返回一个随机数
*
* @return
*/
public int getRandom() {
Log.d(TAG, "==getRandom==");
return mGenerator.nextInt(500);
} @Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "==onUnbind==");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "==onDestroy==");
}
}
5.在Manifest.xml中注册service
<service android:name=".serivice.LocalService"/>
6.在客户端的Activity中绑定service bindService(intnet,ServiceConnection,Context.BINDAUTOCREATE)
7.写一个类实现ServiceConnection接口,在方法中完成获取Service类的实例
8.调用服务中的方法
9.解除绑定
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <Button
android:onClick="bind1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务1"/> <TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/> <Button
android:onClick="show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="调用方法"/> <Button
android:onClick="unBind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="解绑绑定服务1"/>
</LinearLayout>
客户端类
Activity
/**
* 绑定服务
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG ="MainActivity" ;
//服务
private LocalService mService;
private boolean mbound = false;
private MyServiceConnection mConection;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "=====MainActivity==onCreate=====");
tv = (TextView) findViewById(R.id.tv);
}
/**
* 绑定服务
* @param view 按键
*/
public void bind1(View view){
Log.d(TAG, "=====MainActivity==bind1=====");
Intent intent = new Intent(this,LocalService.class);
if(mConection==null){
mConection = new MyServiceConnection();
}
mbound = bindService(intent, mConection, Context.BIND_AUTO_CREATE);
Log.d(TAG, "=====MainActivity==flag=====" + mbound);
}
public void show(View v) {
if (mbound) {
int random = mService.getRandom();
tv.setText(random + "");
}
}
/**
* 服务连接类
*/
private class MyServiceConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalService.LocalBinder mBinder= (LocalService.LocalBinder) service;
mService = mBinder.getServcie();
Log.d(TAG, "=====MainActivity==MyServiceConnection==onServiceConnected===");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG,"=====MainActivity==MyServiceConnection==onServiceDisconnected===");
mbound=false;
}
}
/**
* 解除绑定
* @param v
*/
public void unBind(View v){
Log.d(TAG,"=====MainActivity==unBind======");
if(mService!=null) {
unbindService(mConection);
mConection=null;
}
}
/**
* 销毁
*/
@Override
protected void onDestroy() {
Log.d(TAG,"=====MainActivity==onDestroy======");
super.onDestroy();
if(mService!=null&&mConection!=null) {
unbindService(mConection);
mConection=null;
}
}
}
以上的方式如果只要给自己程序用同时不要把一些方法私有化的话都可以在Service中写public的方法,使用这种方式
8.绑定服务第二种
使用Messenger与Handler的机制处理,这种方式是一种单线程的,不安全的,目前很少有人用了,会造成排队现象
Service
/**
* Created by 刘楠 on 2016-02-28 16:29.
*/
public class MessengerService extends Service { public static final int MSG_SAY_HELLO = 1; Messenger mMessenger = new Messenger(new IncomingHandler()); public class IncomingHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){ case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(),"hello Android===handleMessage==",Toast.LENGTH_SHORT).show(); }
}
} /**
*
* @param intent 意图
* @return
*/
@Nullable //参数可以为空
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "===onBind====", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
清单文件
注册
<service android:name=".service.MessengerService"/>
客户端
public class MainActivity extends AppCompatActivity {
private Messenger mService;
private MyServiceConnection mServiceConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 界面可见时,绑定Service
*/
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent();
intent.setClass(this, MessengerService.class);
if(mServiceConnection==null){
mServiceConnection = new MyServiceConnection();
}
//绑定
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
private class MyServiceConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
/**
* 点击事件
* @param v
*/
public void sayHello(View v) {
Message msg = Message.obtain();
msg.what=MessengerService.MSG_SAY_HELLO;
//发送消息
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mService!=null&&mServiceConnection!=null) {
unbindService(mServiceConnection);
mServiceConnection=null;
}
}
}
9.使用普通接口完成
- 使用接口的方式建立Service
接口
/**
* Created by 刘楠 on 2016-02-28 18:25.
* 接口定义方法让Service中自定义的Binder来实现这个接口,同时调用Service中公用与私有方法
*/
public interface IRemoteService { public void display(String name,int age); public void gogo(); }
建立Service
/**
* Created by 刘楠 on 2016-02-28 18:20.
*/
public class LocalService extends Service {
//自定义的IBinder对象
private LocalBinder mLocalBinder= new LocalBinder(); /**
* 自定义的Binder
* 对面接头的内线
*/
public class LocalBinder extends Binder implements IRemoteService {
//接口的方法
@Override
public void display(String name, int age) {
//调用Service中的方法
show(name,age);
}
//接口的方法
@Override
public void gogo() {
//调用Service中的方法
go();
}
//这里算自定义的方法
public void showData(){
Toast.makeText(getApplicationContext(),new Date().toString(),Toast.LENGTH_SHORT).show();
}
} private static final String TAG ="LocalService" ; @Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG,"=====onBind=======");
return mLocalBinder;
} @Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"=====onCreate=======");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG,"=====onStartCommand=======");
return super.onStartCommand(intent, flags, startId);
} @Override
public boolean onUnbind(Intent intent) {
Log.d(TAG,"=====onUnbind=======");
return super.onUnbind(intent);
} @Override
public void unbindService(ServiceConnection conn) {
super.unbindService(conn);
Log.d(TAG, "=====unbindService=======");
} @Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "=====onDestroy=======");
} /*
上面会调用这个方法
*/
private void show(String name,int age){
Toast.makeText(getApplicationContext(),"姓名:"+name+"年龄:"+age,Toast.LENGTH_SHORT).show();
Log.d(TAG, "====service=show======");
} /*
上面的Binder会调用这个方法
*/ private void go(){
Toast.makeText(getApplicationContext(),"gogogogogogoggog",Toast.LENGTH_SHORT).show();
Log.d(TAG, "====service=go======");
}
}
布局就5个按键
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="bind"
android:text="绑定bindService服务"/> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="callMethod"
android:text="调用服务中的方法"/> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="unBind"
android:text="解除unBindService绑定"/> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="start"
android:text="使用startService开始服务"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="stop"
android:text="使用stopService停止服务"/>
</LinearLayout>
Activity
public class MainActivity extends AppCompatActivity {
private static final String TGA ="MainActivity" ;
//连接的类
private MyServcieConnection mConnection;
//IBinder对象
private LocalService.LocalBinder mLocalBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 绑定服务
*
* @param view 按键
*/
public void bind(View view) {
Log.d(TGA, "========Activity===bind======");
Intent intent = new Intent();
intent.setClass(this, LocalService.class);
if(mConnection==null){
mConnection = new MyServcieConnection();
}
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
/**
* 调用服务中的方法
*
* @param view 按键
*/
public void callMethod(View view) {
Log.d(TGA,"========Activity===callMethod======");
if(mLocalBinder!=null){
//调用方法
mLocalBinder.display("张三",18);
mLocalBinder.gogo();
mLocalBinder.showData();
}
}
/**
* 解除绑定服务
*
* @param view 按键
*/
public void unBind(View view) {
Log.d(TGA,"========Activity===unBind======");
if(mConnection!=null){
unbindService(mConnection);
mConnection=null;
mLocalBinder=null;
}
}
/**
* 开始服务
*
* @param view 按键
*/
public void start(View view) {
Log.d(TGA,"========Activity===start======");
Intent intent = new Intent();
intent.setClass(this, LocalService.class);
startService(intent);
}
/**
* 停止服务
*
* @param view 按键
*/
public void stop(View view) {
Log.d(TGA,"========Activity===stop======");
//停止服务
Intent intent = new Intent();
intent.setClass(this, LocalService.class);
stopService(intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TGA, "========Activity===onDestroy======");
/* if(mConnection!=null){
unbindService(mConnection);
mConnection=null;
mLocalBinder=null;
return;
}
//停止服务
Intent intent = new Intent();
intent.setClass(this, LocalService.class);
stopService(intent);*/
}
/**
* 服务连接类
*/
private class MyServcieConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TGA,"========Activity===onServiceConnected======");
mLocalBinder = (LocalService.LocalBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TGA,"========Activity===onServiceDisconnected======");
}
}
}
注册
<!--注册-->
<service android:name=".service.LocalService"/>
结果:
02-28 06:39:24.895 4350-4350/? D/MainActivity: ========Activity===bind====== 02-28 06:39:24.968 4350-4350/? D/LocalService: =====onCreate=======
02-28 06:39:24.969 4350-4350/? D/LocalService: =====onBind=======
02-28 06:39:24.985 4350-4350/? D/MainActivity: ========Activity===onServiceConnected======
02-28 06:39:28.625 4350-4350/? D/MainActivity: ========Activity===callMethod====== 02-28 06:39:28.631 4350-4350/? D/LocalService: ====service=show======
02-28 06:39:28.637 4350-4350/? D/LocalService: ====service=go======
ace 0xeb9b54a0, error=EGL_SUCCESS
02-28 06:39:30.906 4350-4350/? D/MainActivity: ========Activity===unBind====== 02-28 06:39:30.937 4350-4350/? D/LocalService: =====onUnbind=======
02-28 06:39:30.937 4350-4350/? D/LocalService: =====onDestroy======= 02-28 06:39:32.721 4350-4368/? V/RenderScript: 0xe1f0e200 Launching thread(s), CPUs 4
02-28 06:39:35.827 4350-4350/? D/MainActivity: ========Activity===start====== 02-28 06:39:35.846 4350-4350/? D/LocalService: =====onCreate=======
02-28 06:39:35.846 4350-4350/? D/LocalService: =====onStartCommand=======
02-28 06:39:36.878 4350-4350/? D/MainActivity: ========Activity===stop====== 02-28 06:39:36.902 4350-4350/? D/LocalService: =====onDestroy=======
10.AIDL (AIDL-Android Interface Definition Language)
AIDL可以同时处理多个线程的请求,并且是线程安全的.
To use AIDL directly, you must create an .aidl file that defines the programming interface. The Android SDK tools use this file to generate an abstract class that implements the interface and handles IPC, which you can then extend within your service.
要使用AIDL必须建立一个扩展名为.aidl的文件,SDK会自动生成对象的抽象类同是实现接口与Handles IPC通信,在Service中可以选择继承
例如:支付宝,就只是暴露了,接口给商家使用,里面具体怎么实现并没有暴露
将上面的接口后缀名改为.aidl
更改Serive中的自定义IBinder
public class LocalBinder extends IRemoteService.Stub {
更改客户端 中声明不在写原来的binder
更改这个为
private LocalService.LocalBinder mLocalBinder;
更改后
//IRemoteService
private IRemoteService mIRemoteService;
Activity
public class MainActivity extends AppCompatActivity {
private static final String TGA ="MainActivity" ;
//连接的类
private MyServcieConnection mConnection;
//IRemoteService
private IRemoteService mIRemoteService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 绑定服务
*
* @param view 按键
*/
public void bind(View view) {
Log.d(TGA, "========Activity===bind======");
Intent intent = new Intent();
intent.setClass(this, LocalService.class);
if(mConnection==null){
mConnection = new MyServcieConnection();
}
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
/**
* 调用服务中的方法
*
* @param view 按键
*/
public void callMethod(View view) {
Log.d(TGA,"========Activity===callMethod======");
if(mIRemoteService!=null){
//调用方法
try {
mIRemoteService.display("张三",18);
mIRemoteService.gogo();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
/**
* 解除绑定服务
*
* @param view 按键
*/
public void unBind(View view) {
Log.d(TGA,"========Activity===unBind======");
if(mConnection!=null){
unbindService(mConnection);
mConnection=null;
mIRemoteService=null;
}
}
/**
* 开始服务
*
* @param view 按键
*/
public void start(View view) {
Log.d(TGA,"========Activity===start======");
Intent intent = new Intent();
intent.setClass(this, LocalService.class);
startService(intent);
}
/**
* 停止服务
*
* @param view 按键
*/
public void stop(View view) {
Log.d(TGA,"========Activity===stop======");
//停止服务
Intent intent = new Intent();
intent.setClass(this, LocalService.class);
stopService(intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TGA, "========Activity===onDestroy======");
}
/**
* 服务连接类
*/
private class MyServcieConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TGA,"========Activity===onServiceConnected======");
mIRemoteService =IRemoteService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TGA,"========Activity===onServiceDisconnected======");
}
}
}
这种aidl的方式只能调用Serivce接口中的方法,不能调用Service和自定义Binder中特有的方法 常用于给第三方的应用提供服务 * 通过
IRemoteService.Stub.asInterface(service)
方法得到aidl定义的接口实例
11.startService与bindService的生命周期
- startService与stopService
startService
onCreate---创建服务时只执行一次
onStartCommand ----每次开启服务都会调用
stopService
onDestory--停止服务时多次调用,只会执行一次
*bindService与unBindServcie
bindService
onCreate---创建服务时只执行一次
onBind----多次调用,只执行一次
unBindService
onUnbind----解除时,只执行一次
onDestory----只执行一次
安卓第十三天笔记-服务(Service)的更多相关文章
- Android学习笔记--服务(Service)
1.服务概述 1.服务是Android四大组件之一,在使用上可以分为本地服务和远程服务,本地服务是指在不影响用户操作的情况下在后台默默的执行一个耗时操作,例如下载,音频播放等.远程服务是指可以供其他应 ...
- 安卓第十一天笔记-Intent与inter-filter配置
安卓第十一天笔记-Intent与inter-filter配置 Intent与inter-filter配置 1.Intent对象简述 Android应用中有包含三种重要组件:Activity,Servi ...
- android服务Service(上)- IntentService
Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...
- 【Android】18.1 利用安卓内置的定位服务实现位置跟踪
分类:C#.Android.VS2015: 创建日期:2016-03-04 一.安卓内置的定位服务简介 通常将各种不同的定位技术称为位置服务或定位服务.这种服务是通过电信运营商的无线电通信网络(如GS ...
- AngularJs学习笔记--Managing Service Dependencies
原版地址:http://docs.angularjs.org/guide/dev_guide.services.managing_dependencies angular允许service将其他ser ...
- Android服务Service
安卓Service服务 一 Service简介 Service是运行在后台的,没有界面的,用来处理耗时比较长的.Service不是一个单独的进程,也不是一个单独的线程. Service有两种类型 ...
- Spring Boot 2.X(十三):邮件服务
前言 邮件服务在开发中非常常见,比如用邮件注册账号.邮件作为找回密码的途径.用于订阅内容定期邮件推送等等,下面就简单的介绍下邮件实现方式. 准备 一个用于发送的邮箱,本文是用腾讯的域名邮箱,可以自己搞 ...
- 在 CentOS7 上将自定义的 jar 包注册为 linux 服务 service
在 CentOS7 上将自定义的 jar 包注册为 linux 服务 service 1.在 /etc/rc.d/init.d/ 目录下创建一个名字和服务名完全相同的 shell 脚本文件 joyup ...
- 安卓第十天笔记-fragment
安卓第十天笔记-fragment Fragment(片段) 一.Fragment简介 *Fragment是3.0引入的API,主要为了解决平板,大屏幕手机显示问题 *Fragment代表了Activi ...
随机推荐
- Linux高级编程--08.线程概述
线程 有的时候,我们需要在一个基础中同时运行多个控制流程.例如:一个图形界面的下载软件,在处理下载任务的同时,还必须响应界面的对任务的停止,删除等控制操作.这个时候就需要用到线程来实现并发操作. 和信 ...
- node-gyp rebuild 卡住?
最近 npm install 时候经常遇到在 node-gyp rebuild 那里卡很久的情况(大于十分钟),于是研究了一下输出的错误日志解决了这个问题,在这里分享一下. 首先,请检查 node-g ...
- 叨叨PS那些活
临睡前记得今天技术小结没写...就起来叨叨些使用Photoshop做网站的活吧. 一般网站的建站流程和人员配置是: 1 美工,创建页面的psd图 2 前端工程师,根据psd图,切出html页面 3 后 ...
- Python+Selenium进行UI自动化测试项目中,常用的小技巧3:写入excel表(python,xlsxwriter)
我们在项目中可能用到excel表生成,下面的代码就是对excel表的操作: import xlsxwriter import datetime class write_excel(): def __i ...
- TortoiseSVN的bin目录下面没有svn.exe
自己在idea联合svn时遇到这个问题,然后bd和gg,发现很多人都乱说,说什么TortoiseSVN是客户端,默认不包含svn.exe,需要安装Subversion.bullshit! 之所以没有, ...
- JS 中对象的简单创建和继承
对象的简单创建 1.通过对象直接量创建 比如 var obj = {}; 2.通过new 创建 比如 var obj = new Object(); // 相当于var obj = {}; var a ...
- MVC应用程序中管理(更新)上传的文件
实现上传文件功能,有时上传也会操作出错,能让用户有改正有机会,开发上传文件能有更新的功能. 文件上传时,如果是存储于应用程序某一目录的话,在更新时需要了解一些流程,先是删除旧文件,更新数据表相关信息, ...
- 用javascript去掉字符串空格的办法
今天遇到了以关于JavaScript 中怎么去掉 字符串中前后两段的空格 ,我只好向就得js中也后Trim() 函数,后来试试了不 行,就网上找了下解决方法,其中用到了正则表达式 ,整理了下: < ...
- 重温html5的新增的标签和废除的标签
HTML5已经盛行有段时间了,对于标签的使用,按照规范,哪些该用,哪些不该用,你是否都掌握了呢.今天我在这里详细列举下: 新增的结构标签 section元素 表示页面中的一个内容区 块,比如章节.页眉 ...
- Linq之Lambda表达式
一 什么是LINQ? LINQ即Language Integrated Query(语言集成查询),LINQ是集成到C#和Visual Basic.NET这些语言中用于提供查询数据能力的一个新特性. ...