详解Android中Service AIDL的使用

目录
  • 前言
  • Service基本用法——本地服务
  • 远程服务 —— AIDL
    • 服务端
    • 客户端

前言

有些朋友可能是从事开发工作的时间不是特别的长,所以觉得Service相对与另外两个组件activity、broadcast receiver来说,使用可能并不是特别的多,所以对Service来说,理解不是特别的深入,只是有一个大概的概念,今天就和一块来走一下Service,希望能够帮助到大家对Service有更深入的理解。

Service基本用法——本地服务

我们知道服务分为本地服务和远程服务,而本地服务由于它的启动方式不一样,所以生命周期也就不一样,对Service生命周期不熟悉的朋友,自行去百度一下啊。好了,那么我们分别看一下两种不同的启动方式。

我们先创建好Service:ServiceTest.java

package com.example.administrator.servicetestaidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.IntDef;
import android.util.Log;

public class ServiceTest extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("ServiceTest","  ----->  onCreate");
    }

    @Override
    public int onStartCommand(Intent intent,int flags, int startId) {

        Log.d("ServiceTest","  ----->  onStartCommand");

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        Log.d("ServiceTest","  ----->  onDestroy");

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

在看看MainActivity的代码:

package com.example.administrator.servicetestaidl;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
    private Button startService, stopService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        startService = (Button) findViewById(R.id.start_service);
        stopService = (Button) findViewById(R.id.stop_service);

        /**
         * 开启服务
         */
        startService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent startService = new Intent(MainActivity.this,ServiceTest.class);
                startService(startService);

            }
        });

        /**
         * 停止服务
         */
        stopService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent stopService = new Intent(MainActivity.this,ServiceTest.class);
                stopService(stopService);
            }
        });

    }
}

布局activity_main

<?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:id="@+id/start_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开启服务" />

    <Button
        android:id="@+id/stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服务" />

</LinearLayout>

配置文件AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.administrator.servicetestaidl">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".ServiceTest"
            android:enabled="true"
            android:exported="true"></service>
    </application>

</manifest>

上面的代码很简单,并不难理解,在页面上加两个按钮,一个是启动服务,一个是销毁服务的,并且我们在ServiceTest里面的几个方法都加上了log,那我们点击开启服务,看看Log,如图:

然后我们多次点击开启服务,如图:

我们看到,后面即使多点几下这个开启服务,但是也只会调onStartCommand方法,onCreate方法并不会重复调用,那是因为我们点击Service,由于该service已经存在,所以并不会重新创建,所以onCreate方法只会调用一次。
我们还可以到手机的应用程序管理界面来检查一下Service是不是正在运行,如下图所示:

那当我们点击停止服务按钮呢,看看log:如图

这时候说明了服务已经销毁了。

有些朋友可能注意到了,我们刚刚那种启动服务的方式,好像除了对Service进行开启和销毁以外,很难在activity里进行对Service进行控制,什么意思呢?举个例子,如果说我现在用Service进行下载某些东西,我现在在Service写有下载这两个东西的方法,方法a,方法b,那么我怎样在activity里面控制什么时候调用方法a,什么时候调用方法b呢,如果按照原本的启动方式,好像并不好实现,或者说灵活性很差,那么有没有办法办到呢,接着看Service另一种启动方式。在前面我们有一个方法一直都没有动onBind方法,我们就从这个方法入手,先看ServiceTest代码:

package com.example.administrator.servicetestaidl;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.IntDef;
import android.util.Log;

public class ServiceTest extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("ServiceTest","  ----->  onCreate");
    }

    @Override
    public int onStartCommand(Intent intent,int flags, int startId) {

        Log.d("ServiceTest","  ----->  onStartCommand");

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        Log.d("ServiceTest","  ----->  onDestroy");

    }

    @Override
    public IBinder onBind(Intent intent) {

        return new Mybind();
    }

    class Mybind extends Binder{
        public void getString(){
            Log.d("ServiceTest","  ----->  getString");
        }
    }

}

在ServiceTest中增加了一个内部类Mybind,并且在Mybind中增加一个getString方法,在方法中打印log,然后在onBind方法中返回Mybind对象。

再看看MainActivity的代码

package com.example.administrator.servicetestaidl;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

    private Button startService,stopService,bindService,unbindService;
    private ServiceTest.Mybind mybind;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mybind = (ServiceTest.Mybind) service;
            mybind.getString(); //获取到getString方法
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        startService = (Button) findViewById(R.id.start_service);
        stopService = (Button) findViewById(R.id.stop_service);
        bindService = (Button) findViewById(R.id.bind_service);
        unbindService = (Button) findViewById(R.id.unbind_service);

        /**
         * 开启服务
         */
        startService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent startService = new Intent(MainActivity.this,ServiceTest.class);
                startService(startService);

            }
        });

        /**
         * 停止服务
         */
        stopService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent stopService = new Intent(MainActivity.this,ServiceTest.class);
                stopService(stopService);
            }
        });

        /**
         * 绑定服务
         */
        bindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent bindService = new Intent(MainActivity.this,ServiceTest.class);
                bindService(bindService,connection,BIND_AUTO_CREATE);
            }
        });

        /**
         * 解绑服务
         */
        unbindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(connection);
            }
        });
    }
}

主页面布局:activity_main

<?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:id="@+id/start_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开启服务" />

    <Button
        android:id="@+id/stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服务" />

    <Button
        android:id="@+id/bind_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="绑定服务" />

    <Button
        android:id="@+id/unbind_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="解绑服务" />

</LinearLayout>

可以看到,这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。在onServiceConnected()方法中,我们又通过向下转型得到了MyBind的实例,有了这个实例,Activity和Service之间的关系就变得非常紧密了。现在我们可以在Activity中根据具体的场景来调用MyBind中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。

当我们点击绑定服务的时候,结果如下,如图

点击解绑服务的时候,结果如下,如图

注意:Service 是运行在后台,没有可视化的页面,我们很多时候会把耗时的操作放在Service中执行,但是注意,Service是运行在主线程的,不是在子线程中,Service和Thread没有半毛钱的关系,所以如果在Service中执行耗时操作,一样是需要开起线程,否则会引起ANR,这个需要区别开来。

远程服务 —— AIDL

AIDL(Android Interface Definition Language)是Android接口定义语言的意思,它可以用于让某个Service与多个应用程序组件之间进行跨进程通信,从而可以实现多个应用程序共享同一个Service的功能。实际上实现跨进程之间通信的有很多,
比如广播,Content Provider,但是AIDL的优势在于速度快(系统底层直接是共享内存),性能稳,效率高,一般进程间通信就用它。

既然是跨进程,那必须的有两个应用,一个是service端,一个是client端,然后实现客户端从服务端获取数据。那么我们创建一个服务端,项目结构如图所示:

服务端

我们在服务端下建立一个MyAIDLService.aidl文件,目录结构为如图所示:

然后,我们在MyAIDLService下增加一个获取字符串的方法。代码如下:(注:刚刚建立的aidl文件中存在一个方法,那个方法可以忽略,可以删掉不要)

// MyAIDLService.aidl
package aidl;

// Declare any non-default types here with import statements

interface MyAIDLService {
    //获取String数据
    String getString();
}

创建完aidl文件以后,我们build一下项目,然后会在build - >generated ->source ->aidl->debug下会生成一个aidl文件,那说明AIDL文件已经编译成功。

接着建立一个MyService类,代码如下:

package com.example.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.util.Map;

import aidl.MyAIDLService;

public class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new Mybind();
    }

    class Mybind extends MyAIDLService.Stub {

        @Override
        public String getString() throws RemoteException {
            String string = "我是从服务起返回的";

            return string;
        }
    }
}

代码看起来是不是很熟悉,唯一不一样的就是原来在本地服务的时候内部类继承的是Binder,而现在继承的是MyAIDLService.Stub,继承的是我们刚刚建立的aidl文件,然后实现我们刚刚的定义的getString()方法,在这里,我们只是返回一句话,"我是从服务起返回的"~~~~~~~~~~~

客户端

首先将刚刚在服务端创建的MyAIDLService原封不动的复制到客户端来。(注意:路径要一模一样)。接着我们在客户端的MainActivity中加两个按钮,并且和服务端进行相连,代码如下:

MainActivity

package com.example.administrator.servicetestaidl;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import aidl.MyAIDLService;

public class MainActivity extends Activity {

    private Button bindService,unbindService;
    private TextView tvData;
    private MyAIDLService myAIDLService;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myAIDLService = MyAIDLService.Stub.asInterface(service);
            try {
                String str =  myAIDLService.getString();
                tvData.setText(str);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            myAIDLService = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bindService = (Button) findViewById(R.id.bind_service);
        unbindService = (Button) findViewById(R.id.unbind_service);
        tvData = (TextView) findViewById(R.id.tv_data);

        /**
         * 绑定服务
         */
        bindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction("com.example.service.MyService");
                //从 Android 5.0开始 隐式Intent绑定服务的方式已不能使用,所以这里需要设置Service所在服务端的包名
                intent.setPackage("com.example.service");
                bindService(intent, connection, BIND_AUTO_CREATE);

            }
        });

        /**
         * 解绑服务
         */
        unbindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(connection);
            }
        });
    }
}

大家是不是感觉和连接本地服务的代码差不多,没错,这里只需要注意两个地方,一个是绑定服务的时候,因为从 Android 5.0开始 隐式Intent绑定服务的方式已不能使用,所以这里需要设置Service所在服务端的包名

那么这个action是怎么来的呢,我们回来服务端的AndroidManifest.xml,代码如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.service">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
           >
            <intent-filter>
                <action android:name="com.example.service.MyService" />
            </intent-filter>

        </service>
    </application>

</manifest>

另一个需要注意的就是获取MyAIDLService对象是通过MyAIDLService.Stub.asInterface(service);这里大家需要注意一下的。
不过还有一点需要说明的是,由于这是在不同的进程之间传递数据,Android对这类数据的格式支持是非常有限的,
基本上只能传递Java的基本数据类型、字符串、List或Map等。那么如果我想传递一个自定义的类该怎么办呢?这就必须要让这个类去实现Parcelable接口,并且要给这个类也定义一个同名的AIDL文件。这部分内容并不复杂,而且和Service关系不大,所以就不再详细进行讲解了,感兴趣的朋友可以自己去查阅一下相关的资料。

注意:从服务器复制过来的aidl文件不能直接放到Java文件夹下面,必须建立一个aidl文件夹存放,否则会编译不成功

好了,到这里,基本上就结束了,附上一张效果图:

最后附上源码链接

本地服务源码:https://github.com/343661629/nativeService

远程服务源码:https://github.com/343661629/remoteService

以上就是详解Android中Service AIDL的使用的详细内容,更多关于Android中Service AIDL的使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android8.0适配前台定位服务service的示例代码

    从Android 8.0开始系统为实现降低功耗,对后台应用获取用户位置信息频率进行了限制,每小时只允许更新几次位置信息,详细信息请参考官方说明.按照官方指引,如果要提高位置更新频率,需要后台应用提供一个前台服务通知告知. 所以原来的单单使用locationManager获得当前位置在后台情况下无法使用了.于是打算使用一个前台服务,当app在后台时也能获得当前位置. 查了几篇博客说前台服务需要在service的onStartCommand方法中调用startForeground(int, Noti

  • Android基于AccessibilityService制作的钉钉自动签到程序代码

    前两天公司开始宣布要使用阿里钉钉来签到啦!!!~~这就意味着,我必须老老实实每天按时签到上班下班了,这真是一个悲伤的消息,可是!!!!那么机智(lan)的我,怎么可能就这么屈服!!!阿里钉钉签到,说到底不就是手机软件签到吗?我就是干移动开发的,做一个小应用每天自动签到不就行了:) 说干就干,首先分析一下,阿里钉钉的签到流程: 打开阿里钉钉->广告页停留2S左右->进入主页->点击"工作"tab->点击"签到"模块->进入签到页面(可能会

  • Android通过Service实现简单的音乐播放

    android音乐播放效果,简单的服务开启. 这里将用到android的四大组件之一:Service 注意:Service是自大组件之一,需要注册. 什么是服务? 1:"Service" 意思即"服务"的意思, 像 Windows 上面的服务一样,服务是在后台上运行,承担着静悄悄的不为人所注意的工作. 2:Service运行在后台,它是不可见的.无界面的程序. 3:Service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity,这个时候

  • Android通过AIDL在两个APP之间Service通信

    一.项目介绍 [知识准备] ①Android Interface definition language(aidl,android接口定义语言),其目的实现跨进程的调用.进程是程序在os中执行的载体,一个程序对应一个进程,不同进程就是指不同程序,aidl实现不同程序之间的调用. ②主线程与子线程通信使用handler,handler可以在子线程中发出消息,在主线程处理消息,从而完成线程之间的通信,即使有多个线程,仍然是一个程序. ③不同程序之间需要通过aidl通信,通信方式可以有多种,aidl是

  • 说说在Android如何使用服务(Service)的方法

    Android 服务(Service)适合执行那些不需要和用户交互而且还要求长期运行的任务. 服务的运行不依赖于任何用户界面,即使 APP 被切换到后台,或者打开了另外一个 APP,服务仍然能够保持正常运行. 但是当某个 APP 进程被杀掉时,那么这个 APP 所创建的所有服务也就停止咯. 另外,服务本身并不会自动开启线程,服务代码默认是运行在主线程中的.所以如果需要执行的业务逻辑耗时长,那么为了防止主线程被阻塞,我们必须在服务内部创建子线程来执行这些业务逻辑. 1 定义服务 在 Android

  • Android四大组件之Service详解

    一.Service简介 Service是Android程序中四大基础组件之一,它和Activity一样都是Context的子类,只不过它没有UI界面,是在后台运行的组件. Service是Android中实现程序后台运行的解决方案,它非常适用于去执行那些不需要和用户交互而且还要求长期运行的任务.Service默认并不会运行在子线程中,它也不运行在一个独立的进程中,它同样执行在UI线程中,因此,不要在Service中执行耗时的操作,除非你在Service中创建了子线程来完成耗时操作. 二.Serv

  • 浅谈Android Service服务的高级技巧

    1 前台服务 因为服务的优先级较低,所以当系统内存不足时,可能会回收正在后台运行的服务.如果若要避免服务被回收,可以使用前台服务. 前台服务会一直有一个图标在系统的状态栏中显示,下拉状态栏可以看到更加详细的信息,类似于消息通知效果. public class FirstService extends Service { private static final String TAG = "FirstService"; @Override public void onCreate() {

  • Android-Service实现手机壁纸自动更换

    本文实例为大家分享了Android Service实现自动更换手机壁纸的具体代码,供大家参考,具体内容如下 先看下效果: 使用界面: 划重点,使用service前别忘了给相应的service添加服务 <service android:name=".ChangeService"></service> 具体实现: 首先定义ChangeService类,继承Service访问系统实现壁纸切换 public class ChangeService extends Ser

  • Android使用Service实现简单音乐播放实例

    Service翻译成中文是服务,熟悉Windows 系统的同学一定很熟悉了.Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在后台执行. Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,例如我们打开一个音乐播放器来听音乐,在听音乐的同时也想做下其它的事情,比如上网聊Q.或者上网浏览新闻之类的事情.这样的话,我们就需要用到S

  • 详解Android中Service AIDL的使用

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

  • 详解Android中Service服务的基础知识及编写方法

    首先,让我们确认下什么是service? service就是android系统中的服务,它有这么几个特点:它无法与用户直接进行交互.它必须由用户或者其他程序显式的启动.它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小哦. 那么,什么时候,我们需要使用service呢?         我们知道,service是运行在后台的应用,对于用户来说失去了被关注的焦点.这就跟我们打开了音乐播放之后,便想去

  • 详解Android中的Service

    Service简介: Service是被设计用来在后台执行一些需要长时间运行的操作. Android由于允许Service在后台运行,甚至在结束Activity后,因此相对来说,Service相比Activity拥有更高的优先级. 创建Service: 要创建一个最基本的Service,需要完成以下工作:1)创建一个Java类,并让其继承Service 2)重写onCreate()和onBind()方法 其中,onCreate()方法是当该Service被创建时执行的方法,onBind()是该S

  • 详解Android中的ActivityThread和APP启动过程

    ActiviryThread ActivityThread的初始化 ActivityThread即Android的主线程,也就是UI线程,ActivityThread的main方法是一个APP的真正入口,MainLooper在它的main方法中被创建. //ActivityThread的main方法 public static void main(String[] args) { ... Looper.prepareMainLooper(); ActivityThread thread = ne

  • 详解Android中Intent对象与Intent Filter过滤匹配过程

    如果对Intent不是特别了解,可以参见博文<详解Android中Intent的使用方法>,该文对本文要使用的action.category以及data都进行了详细介绍.如果想了解在开发中常见Intent的使用,可以参见<Android中Intent习惯用法>. 本文内容有点长,希望大家可以耐心读完. 本文在描述组件在manifest中注册的Intent Filter过滤器时,统一用intent-filter表示. 一.概述 我们知道,Intent是分两种的:显式Intent和隐式

  • 详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题

    详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题 今天在项目中实现了一个效果,主要是画一个圆.为了后续使用方便,将这个圆封装在一个自定义Actor(CircleActot)中,后续想显示一个圆的时候,只要创建一个CircleActor中即可. 部分代码如下所示: package com.ef.smallstar.unitmap.widget; import android.content.res.Resources; import

  • 详解Android中图片的三级缓存及实例

    详解Android中图片的三级缓存及实例 为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响 特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知 所以提出三级缓存策略,通过网络.本地.内存三级缓存图片,来减少不必要的网络交互,避免浪费流量

  • 详解Android中Handler的内部实现原理

    本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文<详解Android中Handler的使用方法>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功

  • 详解Android 中AsyncTask 的使用

    详解Android 中AsyncTask 的使用 1.首先我们来看看AsyncTask 的介绍:   Handler 和 AsyncTask 都是android 中用来实现异步任务处理的方式:其中: Handler 实例向 UI 线程发送消息,完成界面更新, 优点:对整个过程控制的比较精细:         缺点:代码相对臃肿,多个任务同时执行时,不易对线程进行精确的控制: AsyncTask :比Handler 更轻量级一些,适用于简单的异步处理: 优点:简单 | 快捷 | 过程可控:    

  • 详解Android中获取软键盘状态和软键盘高度

    详解Android中获取软键盘状态和软键盘高度 应用场景 在Android应用中有时会需要获取软键盘的状态(即软键盘是显示还是隐藏)和软键盘的高度.这里列举了一些可能的应用场景. 场景一 当软键盘显示时,按下返回键应当是收起软键盘,而不是回退到上一个界面,但部分机型在返回键处理上有bug,按下返回键后,虽然软键盘会自动收起,但不会消费返回事件,导致Activity还会收到这次返回事件,执行回退操作,这时就需要判断,如果软键盘刚刚由显示变为隐藏状态,就不执行回退操作. 场景二 当软键盘弹出后,会将

随机推荐