实例讲解Android中的AIDL内部进程通信接口使用

首先描述下我们想要实现的内容,我们希望在一个应用中通过点击按钮,去操作另一个进程中应用的音乐播放功能。

如图,我们点击“播放”时,系统就会去远程调用我们提供的一个service(与当前service不是同一个应用哦),然后操作service中的音乐播放,点击“停止”则会终止播放。想要重新播放的话,必须先点“销毁service”,再点播放按钮哦。(至于这里为什么要先点销毁按钮才能播放,完全是为了给大家展示下,远程调用service时,怎么去解绑service)。

在这个例子中,我们用到了一个非常重要的概念,AIDL。

AIDL(android interface definition language)android接口描述语言,其主要的作用就是允许我们在不同的进程间进行通信。

我们都知道每个应用程序都运行在各自的进程中,并且android平台是不允许不同进程间进行直接的对象数据等传递的。如果我们非要进行进程间的通讯,那么我们就必须将我们的数据对象分解成一个个微小的、可以被操作系统理解的数据单元,然后有序的通过进程边界的检查。

如果让我们自己实现,那么这个过程都愁死一批批的程序人了。幸好android,为我们解决了这个问题,这就是AIDL出现的原因了。

AIDL (Android Interface Definition Language)是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。

注意:AIDL只支持方法,不能定义静态成员,并且方法也不能有类似public等的修饰符;AIDL运行方法有任何类型的参数和返回值,在java的类型中,以下的类型使用时不需要导入包(import),基本数据类型、String、Map、List.当然为了避免出错,建议只要使用了,就导入包。
     
使用AIDL的步骤:

服务端(提供服务):

第一步:定义一个*.aidl文件,该文件里是符合aidl语言规范的接口定义,里面定义了外部应用可以访问的方法。当我们保存该文件的时候,eclipse会自动为我们在gen文件夹下生成一个相应的java接口文件。例如RemoteServiceInterface.java

第二步:定义一个自己的service,    并将其注册到androidManifest.xml文件中,例如:

<service android:name="MyRemoteService">
 <intent-filter>
 <action android:name="cn.com.chenzheng_java.remote"/>
 </intent-filter>
 </service>

注意这里一定要提供一个intent-filter,我们的客户端进程就是通过该action访问到服务端进程的哦。

我们都知道,在实现自己的service时,为了其他应用可以通过bindService来和我们的service进行交互,我们都要实现service中的onBind()方法,并且返回一个继承了Binder的内部类;在这里,eclipse自动为我们生成的RemoteServiceInterface.java中有一个实现了Binder的内部类,RemoteServiceInterface.Stub。AIDL要求我们,在这里不能再直接去实现Binder类了,而是去实现,AIDL提供给我们的Stub类。 实现stub类的同时,AIDL还要求我们同时实现我们在接口中定义的各种服务的具体实现。至此为止,我们的服务端已经和我们的aidl文件绑定到一起了哦。

客户端:

第一步:客户端要想使用该服务,肯定要先知道我们的服务在aidl文件中到底对外提供了什么服务,对吧?所以,第一步,我们要做的就是,将aidl文件拷贝一份到客户端的程序中(这里一定要注意,包路径要和服务端的保持一致哦,例如服务端为cn.com.chenzheng_java.remote.a.aidl,那么在客户端这边也应该是这个路径)。

第二步:我们都知道,想要和service交互,我们要通过bindService方法,该方法中有一个ServiceConnection类型的参数。而我们的主要代码便是在该接口的实现中。

第三步:在ServiceConnection实现类的onServiceConnected(ComponentName name, IBinder service)方法中通过类似remoteServiceInterface = RemoteServiceInterface.Stub.asInterface(service);方式就可以获得远程服务端提供的服务的实例,然后我们就可以通过remoteServiceInterface 对象调用接口中提供的方法进行交互了。(这里的关键是通过*.Stub.asInterface(service);方法获取一个aidl接口的实例哦)

我们前面在服务端中说过了,必须提供一个intent-filter来匹配请求是否合法,所以我们在客户端访问服务的时候,还必须传递包含了匹配action的Intent哦。

下边整体是代码:
 远程服务端:

RemoteServiceInterface.aidl

package cn.com.chenzheng_java.remote;
/**AIDL的语法和Interface的语法稍微有些不同,
*它里面只能有方法,并且java中的那些修饰词如public等,在这里是不支持的.
*当我们在eclipse中添加一个以.aidl结尾的AIDL文件时,如果你的格式正确,那么
*在gen目录下,你就会看到系统根据你提供AIDL文件自动为你生成的相应的java类
*@author chenzheng_java
*/ 

 interface RemoteServiceInterface { 

   void startMusic();
   void stopMusic();
}

MyRemoteService.java

package cn.com.chenzheng_java.remote; 

import java.io.IOException; 

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.os.RemoteException;
/**
 * @description 远程service
 * @author chenzheng_java
 *
 */
public class MyRemoteService extends Service {
  MediaPlayer mediaPlayer;
  @Override
  public IBinder onBind(Intent intent) {
    return new MyBinder();
  }
  @Override
  public void onCreate() {
    /*
     * MediaPlayer.create方法第一个参数实际上为context对象,这里我们直接传递service给它,
     * 是因为service本身也是继承了context的。
     */
     mediaPlayer = MediaPlayer.create(MyRemoteService.this, R.raw.aiweier);
    super.onCreate();
  } 

  /**
   * @description 这里一定要注意,继承的不再是Binder,而是系统自动为我们生成的
   *       Binder的一个内部类,叫做Stub。我们通过继承Stub类,然后实现AIDL
   *       中定义的方法,便等于对接口的方法进行了具体的实现。
   * @author chenzheng_java
   *
   */
  private class MyBinder extends RemoteServiceInterface.Stub{ 

    public void startMusic() throws RemoteException { 

       mediaPlayer.start(); 

    } 

    public void stopMusic() throws RemoteException {
      mediaPlayer.stop();
      try {
        mediaPlayer.prepare();
      } catch (IllegalStateException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
    } 

  } 

}

RemoteServiceActivity.java

package cn.com.chenzheng_java.remote; 

import android.app.Activity;
import android.os.Bundle;
/**
 * 很多人不理解,这里面基本上什么也没实现,为什么还要提供呢?
 * 其实原因是这样的,service代码我们写好了,也在配置文件中注册了,
 * 这样,手机系统就会识别了吗?不是的哦,你至少得将该service所在的
 * 应用运行一次才可以哦。要不手机怎么知道你添加了一个service啊,对吧!
 * @author chenzheng_Java
 *
 */
public class RemoteServiceActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }
}

androidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="cn.com.chenzheng_java.remote"
   android:versionCode="1"
   android:versionName="1.0">
  <uses-sdk android:minSdkVersion="8" /> 

  <application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".RemoteServiceActivity"
         android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity> 

  <service android:name="MyRemoteService">
    <intent-filter>
    <action android:name="cn.com.chenzheng_java.remote"/>
    </intent-filter>
  </service> 

  </application>
</manifest>

客户端:

activity代码:

package cn.com.chenzheng_java; 

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import cn.com.chenzheng_java.remote.RemoteServiceInterface;
/***
 * @author chenzheng_java
 * @description 通过当前activity去调用不同进程中的远程service
 */
public class LocalServiceActivity extends Activity implements OnClickListener {
  String ACTION_NAME = "cn.com.chenzheng_java.remote";
  boolean flag = false;
  Button button_start ;
  Button button_stop ;
  Button button_destroy ; 

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.music); 

    button_start = (Button) findViewById(R.id.button1);
    button_stop = (Button) findViewById(R.id.button2);
    button_destroy = (Button) findViewById(R.id.button3); 

    button_start.setOnClickListener(this);
    button_stop.setOnClickListener(this);
    button_destroy.setOnClickListener(this);
  } 

  RemoteServiceInterface remoteServiceInterface ; 

  private class MyServiceConnection implements ServiceConnection{
    public void onServiceConnected(ComponentName name, IBinder service) {
      remoteServiceInterface = RemoteServiceInterface.Stub.asInterface(service);
      try {
        Log.i("flag", flag+"");
        if(flag){
          Log.i("通知", "已经开始唱歌");
          remoteServiceInterface.startMusic();
        }else{
          Log.i("通知", "已经停止唱歌");
          remoteServiceInterface.stopMusic();
        } 

      } catch (RemoteException e) {
        e.printStackTrace();
      } 

    } 

    public void onServiceDisconnected(ComponentName name) { 

    } 

  } 

  private MyServiceConnection serviceConnection = new MyServiceConnection(); 

  public void onClick(View v) {
    if(v == button_start){
      flag = true;
      Intent intent = new Intent(ACTION_NAME);
      /**
       * Context.BIND_AUTO_CREATE 当绑定service时,如果发现尚未create,那么就先create一个,然后绑定
       */
      bindService(intent, serviceConnection ,Context.BIND_AUTO_CREATE);
    } 

    if(v == button_stop){
      Log.i("通知", "已经点击了停止按钮");
      flag = false;
      Intent intent = new Intent(ACTION_NAME);
      bindService(intent, serviceConnection ,Context.BIND_AUTO_CREATE);
      try {
        remoteServiceInterface.stopMusic();
      } catch (RemoteException e) {
        e.printStackTrace();
      }
    } 

    if(v == button_destroy){
      flag = false;
      Intent intent = new Intent(ACTION_NAME);
      bindService(intent, serviceConnection ,Context.BIND_AUTO_CREATE);
      unbindService(serviceConnection);
    } 

  }
}

music.xml

<?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">
  <Button android:text="播放" android:id="@+id/button1"
    android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  <Button android:text="停止" android:id="@+id/button2"
    android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  <Button android:text="销毁service" android:id="@+id/button3"
    android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>

其他没有粘贴出来的代码都是由系统默认生成的。

AIDL与传递对象

除了上面我们提到的通过service提供音乐播放等类似的服务之外,我们还可以通过service将对象传递回来哦,你知道怎么用吗,先看例子:

当我们点击“获取”时,会从另一个线程的service中获取一个对象,然后将里面的内容读出来。

对于aidl实现以对象的方式交互。主要步骤如下:

服务端:
第一:定义一个实体类,这里是Beauty,定义一个服务接口aidl文件RemoteBeauty.aidl,这里有一点需要注意,我们引用自定义的实体类到aidl中时需要通过import导入包,但是你会发现,即使你导入了包,还是提示找不到,这时候,你要做的是,建一个以实体类名称命名的aidl文件,如Beauty.aidl,在里面添加一句pracelable Beauty。

第二:开始编写Beauty,这里一定要注意,它一定要实现Pracelable接口,该接口是一个序列化的接口,功能和serializable相似,但是功能更加的迅速。此外,在该Beauty内部一定要声明一个public static final Pracelable.Creator<T>CREATOR对象!!除了里面的那个T代表实体类之外,其他的都不准改变哦。

第三:在androidManifest.xml中注册service。并定义好访问该service的action字符串。

客户端:
客户端这边相应的要简单很多,但是要注意的一点是,要将实体类还有aidl文件都拷贝过来哦,而且要保证路径完全一致!!

Beauty.java

package cn.com.chenzheng_java.service; 

import android.os.Parcel;
import android.os.Parcelable;
/**
 *
 * @author chenzheng_java
 * @description Parcelable是android提供的一个比serializable效率更高的序列号接口
 *       这里必须要继承Parcelable哦,不序列号怎么可以传递……对吧?!
 * 在实体类我们要做两件重要的事情:
 * 第一:实现Parcelable接口
 * 第二:定义一个Parcelable.Creator类型的CREATOR对象
 * 第三:要提供一个Beauty.aidl文件,其中内容为parcelable Beauty,定义了之后,在其他aidl文件中引用Beauty时便不会提示出错了。
 * @since 2011/03/18
 *
 */
public class Beauty implements Parcelable { 

  String name ;
  int age ;
  String sex ; 

  public String getName() {
    return name;
  } 

  public void setName(String name) {
    this.name = name;
  } 

  public int getAge() {
    return age;
  } 

  public void setAge(int age) {
    this.age = age;
  } 

  public String getSex() {
    return sex;
  } 

  public void setSex(String sex) {
    this.sex = sex;
  } 

  @Override
  public int describeContents() {
    return 0;
  } 

  /**
   * 将对象序列号
   * dest 就是对象即将写入的目的对象
   * flags 有关对象序列号的方式的标识
   * 这里要注意,写入的顺序要和在createFromParcel方法中读出的顺序完全相同。例如这里先写入的为name,
   * 那么在createFromParcel就要先读name
   */
  @Override
  public void writeToParcel(Parcel dest, int flags) { 

      dest.writeString(name);
      dest.writeInt(age);
      dest.writeString(sex);
  }
  /**
   * 在想要进行序列号传递的实体类内部一定要声明该常量。常量名只能是CREATOR,类型也必须是
   * Parcelable.Creator<T>
   */
  public static final Parcelable.Creator<Beauty> CREATOR = new Creator<Beauty>() { 

    /**
     * 创建一个要序列号的实体类的数组,数组中存储的都设置为null
     */
    @Override
    public Beauty[] newArray(int size) {
      return new Beauty[size];
    } 

    /***
     * 根据序列号的Parcel对象,反序列号为原本的实体对象
     * 读出顺序要和writeToParcel的写入顺序相同
     */
    @Override
    public Beauty createFromParcel(Parcel source) {
      String name = source.readString();
      int age = source.readInt();
      String sex = source.readString();
      Beauty beauty = new Beauty();
      beauty.setName(name);
      beauty.setAge(age);
      beauty.setSex(sex); 

      return beauty;
    }
  };    

}

RemoteService.java

package cn.com.chenzheng_java.service; 

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
/**
 *
 * @author chenzheng_java
 * @description 提供服务的service
 *
 */
public class RemoteService extends Service { 

  @Override
  public IBinder onBind(Intent intent) {
    Log.i("通知", "执行了OnBind");
    return new MyBinder();
  } 

  private class MyBinder extends RemoteBeauty.Stub{ 

    @Override
    public Beauty getBeauty() throws RemoteException { 

      Beauty beauty = new Beauty();
      beauty.setName("feifei");
      beauty.setAge(21);
      beauty.setSex("female"); 

      return beauty;
    }} 

}

ServiceActivity.java

package cn.com.chenzheng_java.service; 

import android.app.Activity;
import android.os.Bundle;
/**
 * @description 进程之间对象数据的传递
 * @author chenzheng_java
 *
 */
public class ServiceActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }
}

Beauty.aidl

parcelable Beauty; 

RemoteBeauty.aidl

package cn.com.chenzheng_java.service;
import cn.com.chenzheng_java.service.Beauty;
 interface RemoteBeauty { 

  Beauty getBeauty(); 

}

manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="cn.com.chenzheng_java.service"
   android:versionCode="1"
   android:versionName="1.0">
  <uses-sdk android:minSdkVersion="8" /> 

  <application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".ServiceActivity"
         android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity> 

<!-- service开始 -->
  <service android:name="RemoteService">
    <intent-filter>
      <action android:name="cn.com.chenzheng_java.remote2"/>
    </intent-filter>
  </service>
<!-- service结束 -->
  </application>
</manifest>

客户端:

ClientActivity.java

package cn.com.chenzheng_java.client; 

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import cn.com.chenzheng_java.service.Beauty;
import cn.com.chenzheng_java.service.RemoteBeauty; 

public class ClientActivity extends Activity implements OnClickListener {
  TextView textView ;
  Button button ;
  String actionName = "cn.com.chenzheng_java.remote2";
  RemoteBeauty remoteBeauty; 

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    textView = (TextView) findViewById(R.id.textView1);
    button = (Button) findViewById(R.id.button1); 

    button.setOnClickListener(this);
  } 

  private class MyServiceConnection implements ServiceConnection{ 

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
      Log.i("通知", "链接成功!");
      remoteBeauty = RemoteBeauty.Stub.asInterface(service);
      try {
        Beauty beauty = remoteBeauty.getBeauty();
        textView.setText("美女 姓名:"+beauty.getName()+" 年龄:"+beauty.getAge() +" 性别:"+beauty.getSex()); 

      } catch (RemoteException e) {
        e.printStackTrace();
      }
    } 

    @Override
    public void onServiceDisconnected(ComponentName name) { 

    } 

  }
  MyServiceConnection connection = new MyServiceConnection();
  @Override
  public void onClick(View v) {
    Intent intent = new Intent(actionName);
    bindService(intent, connection, Context.BIND_AUTO_CREATE);
  }
}

另外Beauty.java 以及RemoteBeauty.aidl都是从服务端系统中拷贝过来的哦。

如果你想你的service在系统开机时自启动。可以在service的androidManifest.xml中加上这样的配置。

<receiver android:name=".StartBroadcastReceiver"> 

      <intent-filter>

  <action android:name="android.intent.action.BOOT_COMPLETED"/>

      </intent-filter>    

</receiver>
(0)

相关推荐

  • Android 使用【AIDL】调用外部服务的解决方法

    在Android 中有一种服务说是服务其实倒不如说是一个接口,这个接口名为:Android Interface Definition Language ,这个接口可提供跨进程访问服务,英文缩写为:AIDL. 此种服务的好处在于,多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据的共享和数据相互操作,下面将通过一个DEMO 演示AIDL 是如何为应用程序之间提供服务的.本文大纲为:•1.创建AIDL 服务端.•2.创建AIDL 客户端.•3.客户端调用服务端提供的服务接口.

  • Android中如何利用AIDL机制调用远程服务

    在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然, Java中是不支持跨进程内存共享的.因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的.在JavaEE中,采用RMI通过序列化传递对象.在Android中,则采用AIDL(Android Interface DefinitionLanguage:接口描述语言)方式实现. AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Andro

  • Android AIDL和远程Service调用示例代码

    Android:AIDL和远程Service调用 本讲的内容,理解起来很难,也许你看了很多资料也看不明白,但是用起来缺简单的要命.所以我们干脆拿一个音乐播放器中进度条的实例来说明一下AIDL和Remote Service的价值和使用方法,你把这个例子跑一边,体会一下就OK了.下面的例子是我 正在准备的项目实例中的一部分. 首先说明一下我们面临的问题,如果看不懂下面的描述请看前面的课程: 第一.我们知道在AndroId中如果需要进行音乐播放,最方面的方法就是使用自带的MediaPlayer对象,如

  • 基于Android AIDL进程间通信接口使用介绍

    AIDL:Android Interface Definition Language,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口. ICP:Interprocess Communication ,内部进程通信. 使用: 1.先创建一个aidl文件,aidl文件的定义和java代码类似,但是!它可以引用其它aidl文件中定义的接口和类,但是不能引用自定义的java类文件中定义的接口和类,要引用自定义的接口或类,需要为此类也定义一个对应的aidl文件,并且此

  • 浅谈Android Aidl 通讯机制

    服务端: 首先是编写一个aidl文件,注意AIDL只支持方法,不能定义静态成员,并且方法也不能有类似public等的修饰符:AIDL运行方法有任何类型的参数和返回值,在java的类型中,以下的类型使用时不需要导入包(import),基本数据类型.String.Map.List.当然为了避免出错,建议只要使用了,就导入包. 然后在服务端启动一个服务并注册,编写一个任意类实现AIDL文件生成的JAVA接口Stub! 最后在service里面实例化你的任意类并且在onBind(Intent a)方法上

  • Android 进程间通信AIDL使用详解

    一.概述 AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来生成用于IPC的代码.从某种意义上说AIDL其实是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据此而生成的一个IInterface的实例代码,AIDL其实是为了避免我们重复编写代码而出现的一个模板 设计AIDL这门语言的目的就是为了实现进程间通信.在Android系统中,每个进程

  • Android编程实现AIDL(跨进程通信)的方法详解

    本文实例讲述了Android编程实现AIDL(跨进程通信)的方法.分享给大家供大家参考,具体如下: 一. 概述: 跨进程通信(AIDL),主要实现进程(应用)间数据共享功能. 二. 实现流程: 1. 服务器端实现: (1)目录结构,如下图: (2)实现*.aidl文件: A. IAIDLService.aidl实现: package com.focus.aidl; import com.focus.aidl.Person; interface IAIDLService { String getN

  • Android AIDL——进程通信机制详解

    Android  AIDL, Android进程机制通信机制,这里就整理下AIDL 的知识,帮助大家学习理解此部分知识! 什么是 AIDL AIDL 全称 Android Interface Definition Language,即 安卓接口描述语言.听起来很深奥,其实它的本质就是生成进程间通信接口的辅助工具.它的存在形式是一种 .aidl 文件,开发者需要做的就是在该文件中定义进程间通信的接口,编译的时候 IDE 就会根据我们的 .aidl 接口文件生成可供项目使用的 .java 文件,这和

  • 实例讲解Android中的AIDL内部进程通信接口使用

    首先描述下我们想要实现的内容,我们希望在一个应用中通过点击按钮,去操作另一个进程中应用的音乐播放功能. 如图,我们点击"播放"时,系统就会去远程调用我们提供的一个service(与当前service不是同一个应用哦),然后操作service中的音乐播放,点击"停止"则会终止播放.想要重新播放的话,必须先点"销毁service",再点播放按钮哦.(至于这里为什么要先点销毁按钮才能播放,完全是为了给大家展示下,远程调用service时,怎么去解绑se

  • 实例讲解Android中SQLiteDatabase使用方法

    SQLite数据库是android系统内嵌的数据库,小巧强大,能够满足大多数SQL语句的处理工作,而SQLite数据库仅仅是个文件而已.虽然SQLite的有点很多,但并不是如同PC端的mysql般强大,而且android系统中不允许通过JDBC操作远程数据库,所以只能通过webservice等手段于php.servlet交互获取数据. SQLiteDatabase类,代表了一个数据库对象,通过SQLiteDatabase来操作管理数据库. 一些基本的用法:   static  SQLiteDat

  • 实例讲解Android中ViewPager组件的一些进阶使用技巧

    我们经常看到使用了ViewPager的App,在每页上面都会有一个滑块来标志当前处于哪一页.在PagerView包里有android.support.v4.view.PagerTitleStrip和android.support.v4.view.PagerTabStrip两个组件,可以在布局文件中,作为ViewPager的子标签,并设定相对与ViewPager的位置(比如顶部).但这两个组件都很丑,并且标题会随着页面一起滑动,所以一般都不用. 其实实现一个滑块标志当前页面也很简单,大概需要两步:

  • 实例讲解Android中的View类以及自定义View控件的方法

    View的简单理解和实例 1.View的基本概念 在Activity显示的控件 都叫做View(View类 是所有的控件类的父类  比如 文本 按钮) 2.在Activity当中获取代表View的对象 Activity读取布局文件生成相对应的 各种View对象 TextView textView=(TextView)findViewBy(R.id.textView) 3.设置view的属性 Activity_mian.xml 这样的xml布局文件中发现了,类似@+id/和@id/到底有什么区别呢

  • 实例讲解Android中ContentProvider组件的使用方法

    ContentProvider基本使用 为了在应用程序之间交换数据,android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过提供ContentPRovider来实现,其他应用程序就可以通过ContentResolver来操作ContentProvider暴露的数据. 实现ContentProvider的步骤: 1)编写一个类,继承ContentProvid

  • 实例讲解Android中的AutoCompleteTextView自动补全组件

    AutoCompleteTextView是一个具有自动补全功能的EditView,当用户输入数据后,AutoCompleteTextView就会将用户输入的数据与他自己的adapter中的数据对比,如果用户数据与adapter中的某条数据的开始部分完全匹配,那么adapter中的这条数据就会出现在下拉提示框中. 其常用属性定义如下 <AutoCompleteTextView android:id="@+id/mp002_top_place_input" android:layou

  • 详解Android中Service AIDL的使用

    目录 前言 Service基本用法--本地服务 远程服务 -- AIDL 服务端 客户端 前言 有些朋友可能是从事开发工作的时间不是特别的长,所以觉得Service相对与另外两个组件activity.broadcast receiver来说,使用可能并不是特别的多,所以对Service来说,理解不是特别的深入,只是有一个大概的概念,今天就和一块来走一下Service,希望能够帮助到大家对Service有更深入的理解. Service基本用法--本地服务 我们知道服务分为本地服务和远程服务,而本地

  • 实例讲解C#中的职责链模式

    大家好,欢迎来到老胡的博客,今天我们继续了解设计模式中的职责链模式,这是一个比较简单的模式.跟往常一样,我们还是从一个真实世界的例子入手,这样大家也对这个模式的应用场景有更深刻的理解. 一个真实的栗子 作为上班族,相信大家对请假都不陌生,每个公司都有自己请假的流程,稍微讲究点的公司还会有细致的规定,比如,3天以内的假期,小组长有权力批准,3天以上的假期就要找更高级别的领导批准.这种制度就是典型的权力越大职责越大--毕竟,批长假的职责只在高级主管那里存在. 除了规定出这样细致的要求之外,大部分公司

  • 实例讲解Java中的synchronized

    一.使用场景 在负责后台开发的时候,很多时候都是提供接口给前端开发人员去调用,会遇到这样的场景: 需要提供一个领奖接口,每个用户名只能领取一次,我们可以将成功领取的用户在数据库用个标记保存起来.如果这个用户再来领取的时候,查询数据库看该用户是否领取过. 但是问题来了,假设用户手速很快,极短时间内点了两次领奖按钮(前端没有进行控制,我们也不能依赖前端去控制).那么可能掉了两次领奖接口,而且有可能第二次调用的时候查询数据库的时候,第一次领奖还没有执行完成更新领奖标记. 这种场景就可以使用到synch

随机推荐