`
wang_peng1
  • 浏览: 3944307 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

service的使用

阅读更多
http://www.androidcompetencycenter.com/2009/01/basics-of-android-part-iii-android-services/

 本文出自:

Many a times the application needs to do some tasks in the background for which user interventions is not required (or very less intervention is required). These background processes keeps working even if user is using some other application on the phone.

To define such background processes android has a concept of Services. Service in android is long lived application component. Service doesn’t implement any User Interface. Common example of service is Media Player application that keeps playing song in the background, file download application that can download the file in the background.

Let’s see how to create a service.

Creating a service

Android has defined a base class for all services as ‘Service’. All the services have to extend from this Service class. Service class defines service lifecycle methods like onCreate(), onStart(), onDestroy(). Here is the example a service class

package com.wissen.testApp.service;
public class MyService extends Service {
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	@Override
	public void onCreate() {
		super.onCreate();
		Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
	}
}
The above service is notifying the user when the service is created and service is destroyed.

Like every thing else in android, Service in android are also associated with the intents. This intent is required while using the service.

The service entry has to be done in the AndroidManifest.xml file along with the service intent as shown below:

<service class=".service.MyService">
<intent-filter>
<action android:value="com.wissen.testApp.service.MY_SERVICE" />
</intent-filter>
</service>
Now our service is created and can be used by the application code.

Using the service:

The application can start the service with the help of Context.startService method. The method will call the onCreate method of the service if service is not already created; else onStart method will be called. Here is the code to start the MyService

..

Intent serviceIntent = new Intent();
serviceIntent.setAction("com.wissen.testApp.service.MY_SERVICE");
startService(serviceIntent);
The service started with startService method will keep on running until stopService() is called or stopSelf() method is called.

Another way to use service is to bind to the service. The service contented this way will be considered required by the system only for as long as the calling context exists. To bind to the service a service connection object need to be created. The service connection object tell the application when the service is connected or disconnected. Here is how you can bind to the service.

…

ServiceConnection conn = new ServiceConnection() {
	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
	Log.i("INFO", "Service bound ");
	@Override
	public void onServiceDisconnected(ComponentName arg0) {
	Log.i("INFO", "Service Unbound ");
	}
	}

	bindService(new Intent("com.wissen.testApp.service.MY_SERVICE"), conn, Context.BIND_AUTO_CREATE);
}
…

The application can communicate with the service when application is connected with the service. Generally the service communicate is done with the help of Service Interface. Service interface defines methods for which service can provider implementation. For example here is some interface:

package com.wissen.testApp;
public interface IMyService {
public int getStatusCode();
}
Using this interface the application can ask the Service about its status. Lets see how the service can support this interface. Previously we saw a method called onBind which return IBinder object, the method gets called when some client of the service binds to the service. This is the same object that is passed to the onServiceConnected method. The application can communicate with the service using this IBinder object. Here is how this can be done:

 

public class MyService extends Service {
	private int statusCode;
	private MyServiceBinder myServiceBinder = new MyServiceBinder();
	@Override
	public IBinder onBind(Intent intent) {
		return myServiceBinder; // object of the class that implements Service
								// interface.
	}
	public class MyServiceBinder extends Binder implements IMyService {

		public int getStatusCode() {
			return statusCode;
		}
	}
	// .......
}
 

And here is how application can call getStatusCode method:

 

	ServiceConnection conn = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			IMyService myService = (IMyService) service;
			statusCode = myService.getStatusCode();
			Log.i("INFO", "Service bound ");
		}
		// ........
	};

You can also define ServiceListener interface which the client of the service has to be implemented to gets update from the service. In that case the service interface will have to define methods to register and unregister the ServiceListener objects.

Communication with Remote Service:

The services that we defined until now run in the application processes, you can define service that can run in their own process. For two processes to communicate with each other they need to marshal the object to sent to other process.

Android provide an AIDL tool (Android Interface definition Language) to handle all marshalling and communication part.

 

The service has to provide the Service interface as an aidl file. The AIDL tool will create a java interface corresponding for the aidl Service Interface. The AIDL tool also defines a stub class in the generated service interface, which implements the Service Interface (as abstract methods) and also provides some other required functionality. The service interface implementation class has to extend this stub class and define the service interface methods. The service onBind method will return object of this implementation class so that the client application can use the service methods. Here is the how the communication can be done:

Create a file as IMyRemoteService.aidl as follows:

 

package com.wissen.testApp;

interface IMyRemoteService {
int getStatusCode();
}
The eclipse android plug-in will create a Java interface for the aidl file created above as the part of build process.

The interface generated above will have a Stub inner class. Define a class that extends this stub class. Here is the code for the RemoteService class:

package com.wissen.testApp;
class RemoteService implements Service {
	int statusCode;

	@Override
	public IBinder onBind(Intent arg0) {
		return myRemoteServiceStub;
	}
	private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
		public int getStatusCode() throws RemoteException {
			return 0;
		}
	};
	// ........
}
When the client application connect to the service the onServiceConnected method will be called and client will get the IBinder object of the service. The Stub class also provides a method to obtain the Service Interface object from the IBinder object. Here is the client onServiceConnected code

 

…

	ServiceConnection conn = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			IMyRemoteService myRemoteService = IMyRemoteService.Stub
					.asInterface(service);

			try {

				statusCode = myRemoteService.getStatusCode();
			} catch (RemoteException e) {

				// handle exception

			}

			Log.i("INFO", "Service bound ");
		}
		// .........
	};

Permissions:

Service may specify required user permissions in the AndroidManifest.xml in <service> tag like this,

<service class=".service.MyService" android:permission="com.wissen.permission.MY_SERVICE_PERMISSION">
<intent-filter>
<action android:value="com.wissen.testApp.service.MY_SERVICE" />
</intent-filter>
</service>
Then to use above service the application has to ask for permission with the help of <user-permission> tag as follows:

<uses-permission android:name="com.wissen.permission.MY_SERVICE_PERMISSION"></uses-permission>
So in today’s post we saw how to create service and use it. In the next post we will see how to use ContentProviders. 

 

2.

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.exampleservice"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  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=".MyService"></service>
    </application>
    <uses-sdk android:minSdkVersion="8" />
</manifest> 
res\values\strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ExampleService</string>
    <string name="service_started">Example Service started</string> 
    <string name="service_label">Example Service Label</string> 
</resources>
res\layout\main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content">
<Button android:id="@+id/btnStart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start Service"></Button>
<Button android:id="@+id/btnStop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Stop Service" android:layout_alignParentRight="true"></Button>
</RelativeLayout>

<RelativeLayout android:id="@+id/RelativeLayout02" android:layout_width="fill_parent" android:layout_height="wrap_content">
<Button android:id="@+id/btnBind" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bind to Service"></Button>
<Button android:id="@+id/btnUnbind" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Unbind from Service" android:layout_alignParentRight="true"></Button>
</RelativeLayout>

<TextView android:id="@+id/textStatus" android:textSize="24sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Status Goes Here" />
<TextView android:id="@+id/textIntValue" android:textSize="24sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Integer Value Goes Here" />
<TextView android:id="@+id/textStrValue" android:textSize="24sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="String Value Goes Here" />

<RelativeLayout android:id="@+id/RelativeLayout03" android:layout_width="fill_parent" android:layout_height="wrap_content">
<Button android:id="@+id/btnUpby1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Increment by 1"></Button>
<Button android:id="@+id/btnUpby10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Increment by 10" android:layout_alignParentRight="true"></Button>
</RelativeLayout>

</LinearLayout>

 

src\com.exampleservice\MainActivity.java:

package com.exampleservice;

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.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
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;

public class MainActivity extends Activity {
    Button btnStart, btnStop, btnBind, btnUnbind, btnUpby1, btnUpby10;
    TextView textStatus, textIntValue, textStrValue;
    Messenger mService = null;
    boolean mIsBound;
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MyService.MSG_SET_INT_VALUE:
                textIntValue.setText("Int Message: " + msg.arg1);
                break;
            case MyService.MSG_SET_STRING_VALUE:
                String str1 = msg.getData().getString("str1");
                textStrValue.setText("Str Message: " + str1);
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mService = new Messenger(service);
            textStatus.setText("Attached.");
            try {
                Message msg = Message.obtain(null, MyService.MSG_REGISTER_CLIENT);
                msg.replyTo = mMessenger;
                mService.send(msg);
            } catch (RemoteException e) {
                // In this case the service has crashed before we could even do anything with it
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been unexpectedly disconnected - process crashed.
            mService = null;
            textStatus.setText("Disconnected.");
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStart = (Button)findViewById(R.id.btnStart);
        btnStop = (Button)findViewById(R.id.btnStop);
        btnBind = (Button)findViewById(R.id.btnBind);
        btnUnbind = (Button)findViewById(R.id.btnUnbind);
        textStatus = (TextView)findViewById(R.id.textStatus);
        textIntValue = (TextView)findViewById(R.id.textIntValue);
        textStrValue = (TextView)findViewById(R.id.textStrValue);
        btnUpby1 = (Button)findViewById(R.id.btnUpby1);
        btnUpby10 = (Button)findViewById(R.id.btnUpby10);

        btnStart.setOnClickListener(btnStartListener);
        btnStop.setOnClickListener(btnStopListener);
        btnBind.setOnClickListener(btnBindListener);
        btnUnbind.setOnClickListener(btnUnbindListener);
        btnUpby1.setOnClickListener(btnUpby1Listener);
        btnUpby10.setOnClickListener(btnUpby10Listener);

        restoreMe(savedInstanceState);

        CheckIfServiceIsRunning();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("textStatus", textStatus.getText().toString());
        outState.putString("textIntValue", textIntValue.getText().toString());
        outState.putString("textStrValue", textStrValue.getText().toString());
    }
    private void restoreMe(Bundle state) {
        if (state!=null) {
            textStatus.setText(state.getString("textStatus"));
            textIntValue.setText(state.getString("textIntValue"));
            textStrValue.setText(state.getString("textStrValue"));
        }
    }
    private void CheckIfServiceIsRunning() {
        //If the service is running when the activity starts, we want to automatically bind to it.
        if (MyService.isRunning()) {
            doBindService();
        }
    }

    private OnClickListener btnStartListener = new OnClickListener() {
        public void onClick(View v){
            startService(new Intent(MainActivity.this, MyService.class));
        }
    };
    private OnClickListener btnStopListener = new OnClickListener() {
        public void onClick(View v){
            doUnbindService();
            stopService(new Intent(MainActivity.this, MyService.class));
        }
    };
    private OnClickListener btnBindListener = new OnClickListener() {
        public void onClick(View v){
            doBindService();
        }
    };
    private OnClickListener btnUnbindListener = new OnClickListener() {
        public void onClick(View v){
            doUnbindService();
        }
    };
    private OnClickListener btnUpby1Listener = new OnClickListener() {
        public void onClick(View v){
            sendMessageToService(1);
        }
    };
    private OnClickListener btnUpby10Listener = new OnClickListener() {
        public void onClick(View v){
            sendMessageToService(10);
        }
    };
    private void sendMessageToService(int intvaluetosend) {
        if (mIsBound) {
            if (mService != null) {
                try {
                    Message msg = Message.obtain(null, MyService.MSG_SET_INT_VALUE, intvaluetosend, 0);
                    msg.replyTo = mMessenger;
                    mService.send(msg);
                } catch (RemoteException e) {
                }
            }
        }
    }


    void doBindService() {
        bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
        textStatus.setText("Binding.");
    }
    void doUnbindService() {
        if (mIsBound) {
            // If we have received the service, and hence registered with it, then now is the time to unregister.
            if (mService != null) {
                try {
                    Message msg = Message.obtain(null, MyService.MSG_UNREGISTER_CLIENT);
                    msg.replyTo = mMessenger;
                    mService.send(msg);
                } catch (RemoteException e) {
                    // There is nothing special we need to do if the service has crashed.
                }
            }
            // Detach our existing connection.
            unbindService(mConnection);
            mIsBound = false;
            textStatus.setText("Unbinding.");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            doUnbindService();
        } catch (Throwable t) {
            Log.e("MainActivity", "Failed to unbind from the service", t);
        }
    }
}

src\com.exampleservice\MyService.java:

package com.exampleservice;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class MyService extends Service {
    private NotificationManager nm;
    private Timer timer = new Timer();
    private int counter = 0, incrementby = 1;
    private static boolean isRunning = false;

    ArrayList<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.
    int mValue = 0; // Holds last value set by a client.
    static final int MSG_REGISTER_CLIENT = 1;
    static final int MSG_UNREGISTER_CLIENT = 2;
    static final int MSG_SET_INT_VALUE = 3;
    static final int MSG_SET_STRING_VALUE = 4;
    final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler.


    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
    class IncomingHandler extends Handler { // Handler of incoming messages from clients.
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_REGISTER_CLIENT:
                mClients.add(msg.replyTo);
                break;
            case MSG_UNREGISTER_CLIENT:
                mClients.remove(msg.replyTo);
                break;
            case MSG_SET_INT_VALUE:
                incrementby = msg.arg1;
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }
    private void sendMessageToUI(int intvaluetosend) {
        for (int i=mClients.size()-1; i>=0; i--) {
            try {
                // Send data as an Integer
                mClients.get(i).send(Message.obtain(null, MSG_SET_INT_VALUE, intvaluetosend, 0));

                //Send data as a String
                Bundle b = new Bundle();
                b.putString("str1", "ab" + intvaluetosend + "cd");
                Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
                msg.setData(b);
                mClients.get(i).send(msg);

            } catch (RemoteException e) {
                // The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
                mClients.remove(i);
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("MyService", "Service Started.");
        showNotification();
        timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 0, 100L);
        isRunning = true;
    }
    private void showNotification() {
        nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence text = getText(R.string.service_started);
        // Set the icon, scrolling text and timestamp
        Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis());
        // The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);
        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        nm.notify(R.string.service_started, notification);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("MyService", "Received start id " + startId + ": " + intent);
        return START_STICKY; // run until explicitly stopped.
    }

    public static boolean isRunning()
    {
        return isRunning;
    }


    private void onTimerTick() {
        Log.i("TimerTick", "Timer doing work." + counter);
        try {
            counter += incrementby;
            sendMessageToUI(counter);

        } catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
            Log.e("TimerTick", "Timer Tick Failed.", t);            
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (timer != null) {timer.cancel();}
        counter=0;
        nm.cancel(R.string.service_started); // Cancel the persistent notification.
        Log.i("MyService", "Service Stopped.");
        isRunning = false;
    }
}

  • 大小: 27.3 KB
分享到:
评论

相关推荐

    Service使用demo(Eclipse)

    本示例"Service使用demo(Eclipse)"将深入讲解如何在Eclipse环境中集成并运用Service,同时结合BroadcastReceiver实现更灵活的应用场景。 首先,我们来详细了解Service的基本概念。Service主要分为两种类型:START...

    Reporting Service 使用方法

    Reporting Service 使用方法 Reporting Service 是 SQL Server 2008 中的一项功能强大且灵活的报表生成工具。它允许开发者快速创建专业的报表,满足业务需求。Reporting Service 提供了一个友好的设计器环境,允许...

    Android Service使用注意事项1

    以下是关于"Android Service使用注意事项1"的详细解释: 1. **注册Service** 在Android系统中,所有的组件(包括Service)都必须在`AndroidManifest.xml`文件中声明注册,以便系统知道它们的存在。没有注册的...

    Service服务的各种使用方式

    在Android开发中,Service是四大组件之一,它用于在后台执行...理解并熟练运用各种Service使用方式,能够帮助开发者实现丰富的后台功能,提升应用体验。通过ServiceDemo项目,初学者可以更直观地学习和实践这些知识点。

    进程内Activity和service使用Binder通信代码备份

    3. Activity绑定Service并使用Binder:在Activity中,我们可以通过bindService()方法绑定到Service,并在onServiceConnected()回调中获取到Binder对象。之后就可以调用Service中定义的方法了。 ```java public ...

    android service使用小demo

    android service使用的小demo 包括startService stopService bindService unbindService 两种开启、关闭service的小demo

    android service使用详解

    本篇文章将深入探讨如何在Android中使用Service。 一、Service的基本概念 Service是Android系统中的一个特殊组件,它可以在后台运行,不与用户界面直接交互。Service可以启动(Start)或绑定(Bind),两种方式各有...

    Android Service使用示例

    本示例将详细介绍如何使用 `Service`,特别是 `Start Service` 和 `Bind Service` 两种启动方式,以及如何实现 `Service` 与 `Activity` 之间的数据交互。 ### 1. Start Service `Start Service` 主要用于启动一个...

    qt-solutions-master 源码和qtservice使用案例

    qt-solutions-master 源码和qtservice使用案例工程,包括qtservice,qtbrowserplugin,qtlockedfile,qtpropertybrowser,qtscriptclassic,qtsingleapplication,qtsoap,qtwinmigrate源码qtservice使用案例工程。...

    Service使用Demo

    本教程将通过"Service使用Demo"来详细介绍Service的基本用法及其应用场景。 1. **Service生命周期** Service的生命周期包括创建(onCreate())、启动(onStartCommand())、绑定(onBind())、停止(onStop())和...

    IOTService_使用说明_202007081

    本文将详细介绍"IOTService"的使用说明,包括其工具安装、串口服务器设备连接、功能特性以及测试指导。IOTService是一个专为物联网(IoT)设计的服务平台,它提供了丰富的功能,如串口服务器设备管理、邮件报警、远程...

    service使用及发送通知

    本教程将深入探讨如何使用`Service`,以及在绑定的`Service`中发送`Notification`。 ### 1. 创建和启动Service 创建一个`Service` 需要继承 `android.app.Service` 类,并重写必要的生命周期方法,如 `onCreate()`...

    同一应用同一进程内部Service使用

    本主题将深入探讨“同一应用同一进程内部Service的使用”,包括Service的基本概念、为何在同一进程中使用、如何创建与启动,以及相关注意事项。 ### Service基础 Service是一种没有用户界面的组件,它可以在后台...

    Android开发-Activity与Service使用Messenger通信代码

    这就是使用Messenger进行Activity和Service通信的基本流程。这种通信方式相对简单,适用于需要频繁、轻量级的消息传递。然而,如果需要传输大量数据或复杂的对象,可能需要考虑其他如AIDL(Android Interface ...

    Service使用

    - **停止Service**:要停止已启动的服务,可以使用 `stopService()` 方法,传入服务的 Intent。当 `onDestroy()` 方法被调用时,表示服务已被停止。 2. **Service的绑定和解绑** - **绑定Service**:绑定服务允许...

    Linux运维-运维课程MP4频-05容器-72dockerswarm网络存储卷-编排部署service使用卷.mp4

    Linux运维-运维课程MP4频-05容器-72dockerswarm网络存储卷-编排部署service使用卷.mp4

    Linux运维-运维课程MP4频-05容器-71dockerswarm网络存储卷-手动创建service使用卷.mp4

    Linux运维-运维课程MP4频-05容器-71dockerswarm网络存储卷-手动创建service使用卷.mp4

    fontgen-loader, 从SVG图标自动生成 webfont web service使用 !.zip

    fontgen-loader, 从SVG图标自动生成 webfont web service使用 ! fontgen-loader - Bam,轻松 webfonts !你遇到了这个你有 4个图标,从FontAwesome到 19,也许你是eying的另一个图标,希望使用它们?真是一团糟行了...

    辅助服务类:AccessibilityService使用

    依据Android官方文档,考虑到一些用户不能很好地使用Android设备,比如由于视力、身体、年龄方面的限制,造成阅读内容、触控操作、声音信息等方面的获取困难,因此Android提供了Accessibility特性和服务帮助用户更好...

    详解Android Service 使用时的注意事项

    "详解Android Service 使用时的注意事项" Android Service 使用时的注意事项是一个非常重要的 topic,对于 Android 开发者来说,了解 Service 的使用要点和注意事项是非常必要的。下面我们将详细介绍 Android ...

Global site tag (gtag.js) - Google Analytics