綁定的方式調用服務的方法
服務的生命週期:
一、採用start的方式開啓服務
生命週期如下:
onStart()過時了
開啓服務:onCreate()--> onStartCommand() ---> onDestory();
如果服務已經開啓,不會重複的執行onCreate(), 而是會調用onStart()和 onStartCommand();
服務停止的時候onDestory().
服務只會被停止一次
二、服務還有一種開啓方式,綁定的方式開啓服務。
onCreate()--->onBind();--->onunbind()-->onDestory();
綁定服務不會調用onstart或者onstartcommand方法;
混合調用的服務的生命週期:
服務長期後臺運行,又想調用服務的方法:
1.start方式開啓服務(保證服務長期後臺運行)
2.bind方式綁定服務(保證調用服務的方法)
3.unbind解除綁定服務
4.stopService停止服務。
三、兩種開啓服務方法的區別。
start方式開啓服務。一旦服務開啓跟調用者(開啓者)就沒有任何關係了。
開啓者退出了,開啓者掛了,服務還在後臺長期的運行。
開啓者沒有辦法去調用服務裏面的方法。(美國的司法獨立)
bind的方式開啓服務,綁定服務,調用者掛了,服務也會跟着掛掉。不求同時生,但求同時死。
開啓者可以調用服務裏面的方法。服務的生命週期
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="start"
android:text="開啓服務" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="stop"
android:text="停止服務" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="call"
android:text="調用服務裏面的方法" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.servicelife"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.servicelife.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="com.itheima.servicelife.MyService"></service>
</application>
</manifest>
package com.itheima.servicelife;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start(View view){
Intent intent = new Intent(this,MyService.class);
//通知框架開啓服務。
startService(intent);
}
public void stop(View view){
Intent intent = new Intent(this,MyService.class);
stopService(intent);
}
@Override
protected void onDestroy() {
System.out.println("啊啊啊,我是activity,我掛了");
super.onDestroy();
}
//調用服務裏面的方法。不可以自己new服務,調用的服務的方法,必須通過框架得到服務的引用。
public void call(View view){
}
}
package com.itheima.servicelife;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
System.out.println("oncreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onstartcommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
System.out.println("ondestory");
super.onDestroy();
}
/**
* 這是服務裏面的一個方法
*/
public void methodInService(){
Toast.makeText(this, "哈哈,我是服務裏面的方法", 0).show();
}
}
綁定服務
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="bind"
android:text="綁定服務" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="unbind"
android:text="解除綁定服務" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="call"
android:text="調用服務裏面的方法" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.servicelife"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.servicelife.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="com.itheima.servicelife.MyService"></service>
</application>
</manifest>
package com.itheima.servicelife;
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;
public class MainActivity extends Activity {
private MyConn conn ;
private IMiddlePerson mp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//綁定服務
public void bind(View view){
//3.activity採用綁定的方式去開啓服務。
Intent intent = new Intent(this,MyService.class);
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
//解除綁定服務
public void unbind(View view){
unbindService(conn);
}
@Override
protected void onDestroy() {
System.out.println("啊啊啊,我是activity,我掛了");
super.onDestroy();
}
//調用服務裏面的方法。
public void call(View view){
//5.通過中間人調用服務裏面的方法。
mp.callMethodInService(55);
}
private class MyConn implements ServiceConnection{
//4. 當服務被連接的時候調用 服務別成功 綁定的時候調用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("在activity裏面成功得到了中間人");
mp = (IMiddlePerson) service;
}
//當服務失去連接的時候調用(一般進程掛了,服務被異常殺死)
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
採用接口抽取方法
package com.itheima.servicelife;
/**
* 中間人的接口定義
*
*/
public interface IMiddlePerson {
/**
* 代辦暫住證
* @param money
*/
public void callMethodInService(int money);
}
package com.itheima.servicelife;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
//2.實現服務成功綁定的代碼 ,返回一箇中間人。
@Override
public IBinder onBind(Intent arg0) {
System.out.println("服務被成功綁定了。。。。");
return new MiddlePerson();
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("onunbind");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
System.out.println("oncreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onstartcommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
System.out.println("ondestory");
super.onDestroy();
}
/**
* 這是服務裏面的一個方法
*/
public void methodInService(){
Toast.makeText(this, "哈哈,服務給你辦好了暫住證。", 0).show();
}
//1.第一步服務要暴露方法 必須要有一箇中間人
private class MiddlePerson extends Binder implements IMiddlePerson{
/**
* 代辦暫住證
* @param money 給錢 50塊錢以上纔給辦。
*/
public void callMethodInService(int money){
if(money>=50){
methodInService();
}else{
Toast.makeText(getApplicationContext(), "多準備點錢。", 0).show();
}
}
/**
* 陪領導打麻將
*/
public void playMajiang(){
System.out.println("陪領導打麻將。");
}
}
}
aidl綁定遠程服務
遠程服務
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.remoteservice"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.remoteservice.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="com.itheima.remoteservice.RemoteService">
<intent-filter >
<action android:name="com.itheima.remoteservice"/>
</intent-filter>
</service>
</application>
</manifest>
package com.itheima.remoteservice;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
package com.itheima.remoteservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class RemoteService extends Service {
@Override
public void onCreate() {
System.out.println("遠程服務被創建了。。。");
super.onCreate();
}
@Override
public void onDestroy() {
System.out.println("遠程服務被銷燬了。");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return new MiddlePerson();
}
private void methodInService(){
System.out.println("我是遠程服務的方法,我被調用了。。。。");
}
//1.創建一箇中間人 遠程服務繼承的是ipc的一個實現類
private class MiddlePerson extends IMiddlePerson.Stub{
@Override
public void callMethodInService() {
methodInService();
}
}
}
IMiddlePerson.aidl
package com.itheima.remoteservice;
interface IMiddlePerson {
/**
* 調用服務裏面的方法
*/
void callMethodInService();
}
綁定遠程服務
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:onClick="bind"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="綁定遠程服務" />
<Button
android:onClick="unbind"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="解除綁定遠程服務" />
<Button
android:onClick="call"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="調用遠程服務的方法" />
</LinearLayout>
IMiddlePerson.aidl
package com.itheima.remoteservice;
interface IMiddlePerson {
/**
* 調用服務裏面的方法
*/
void callMethodInService();
}
package com.itheima.bindremote;
import com.itheima.remoteservice.IMiddlePerson;
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;
public class MainActivity extends Activity {
private MyConn conn;
private IMiddlePerson iMp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 綁定遠程服務
* @param view
*/
public void bind(View view){
Intent intent = new Intent();
intent.setAction("com.itheima.remoteservice");
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
private class MyConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMp = IMiddlePerson.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
public void call(View view){
try {
iMp.callMethodInService();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.bindremote"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.bindremote.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>
</application>
</manifest>
遠程服務:調用者和服務在不同的工程代碼裏面。
本地服務:調用者和服務在同一個工程代碼裏面。
每一個應用程序都是運行在自己獨立的進程裏面的。
進程操作系統分配內存空間的一個單位。進程的數據都是獨立的。獨立的內存空間。
aidl:android interface definition language 安卓接口定義語言
aidl文件都是公有的,沒有訪問權限修飾符
IPC: inter process communication 進程間通訊
綁定本地服務調用方法的步驟:
1.在服務的內部創建一個內部類 提供一個方法,可以間接調用服務的方法
private class MiddlePerson extends Binder implements IMiddlePerson{}
2.實現服務的onbind方法,返回的就是中間人 MiddlePerson
3.在activity 綁定服務。bindService();
4.在服務成功綁定的時候 會執行一個方法 onServiceConnected 傳遞過來一個 IBinder對象
5.強制類型轉化 調用接口裏面的方法。
綁定遠程服務調用方法的步驟:
1.在服務的內部創建一個內部類 提供一個方法,可以間接調用服務的方法
2.把暴露的接口文件的擴展名改爲aidl文件 去掉訪問修飾符 public
private class MiddlePerson extends IMiddlePerson.Stub{} IPC的子類
3.實現服務的onbind方法,返回的就是中間人 IMiddlePerson
4.在activity 綁定服務。bindService();
5.在服務成功綁定的時候 會執行一個方法 onServiceConnected 傳遞過來一個 IBinder對象
6.IMiddlePerson.Stub.asInterface(binder) 調用接口裏面的方法。
綁定服務的應用場景
getSystemService();
混合調用服務的案例
支付寶
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.alipay"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.alipay.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="com.itheima.alipay.SafePayService">
<intent-filter >
<action android:name="com.itheima.alipay"/>
</intent-filter>
</service>
</application>
</manifest>
package com.itheima.alipay;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
package com.itheima.alipay;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
public class SafePayService extends Service {
@Override
public IBinder onBind(Intent intent) {
System.out.println("服務被綁定 onbind");
return new MyBinder();
}
/**
* 安全支付的方法
*/
private boolean pay(long time,String pwd,double money){
if("123".equals(pwd)){
return true;
}else{
return false;
}
}
private class MyBinder extends ISafePay.Stub{
/**
* 調用安全支付的邏輯
*/
@Override
public boolean callPay(long time, String pwd, double money)
throws RemoteException {
return pay(time, pwd, money);
}
}
@Override
public void onCreate() {
System.out.println("oncreate支付寶服務被創建,一直在後臺運行,檢查手機的安全狀態");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("服務onstart");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("onunbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
System.out.println("ondestory支付寶服務被銷燬");
super.onDestroy();
}
}
package com.itheima.alipay;
interface ISafePay{
boolean callPay(long time,String pwd,double money);
}
捕魚達人
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.fish"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.fish.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>
</application>
</manifest>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="click"
android:text="買5個炮彈" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="start"
android:text="開啓服務" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="stop"
android:text="停止服務" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="bind"
android:text="綁定服務" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="unbind"
android:text="解除綁定服務" />
</LinearLayout>
package com.itheima.alipay;
interface ISafePay{
boolean callPay(long time,String pwd,double money);
}
package com.itheima.fish;
import com.itheima.alipay.ISafePay;
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.Toast;
public class MainActivity extends Activity {
private ISafePay iSafePay;
private MyConn conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Intent intent = new Intent();
// intent.setAction("com.itheima.alipay");
// startService(intent);
//保證服務長期後臺運行。
}
public void start(View view){
Intent intent = new Intent();
intent.setAction("com.itheima.alipay");
startService(intent);
}
public void stop(View view){
Intent intent = new Intent();
intent.setAction("com.itheima.alipay");
stopService(intent);
}
public void bind(View view){
Intent intent = new Intent();
intent.setAction("com.itheima.alipay");
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);//異步的操作
}
public void unbind(View view){
unbindService(conn);
}
public void click(View view){
Intent intent = new Intent();
intent.setAction("com.itheima.alipay");
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);//異步的操作
//綁定服務調用服務的方法。
}
private class MyConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iSafePay = ISafePay.Stub.asInterface(service);
try {
boolean result = iSafePay.callPay(System.currentTimeMillis(), "123", 3.52f);
if(result){
Toast.makeText(getApplicationContext(), "支付成功,獲取大炮彈", 0).show();
}else{
Toast.makeText(getApplicationContext(), "支付失敗,請重試", 0).show();
}
// unbindService(conn);
// conn = null;
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
混合調用的服務的生命週期:
服務長期後臺運行,又想調用服務的方法:
1.start方式開啓服務(保證服務長期後臺運行)
2.bind方式綁定服務(保證調用服務的方法)
3.unbind解除綁定服務
4.stopService停止服務。
加載大圖片到內存
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:onClick="click"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="加載圖片到內存" />
<ImageView
android:id="@+id/iv"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.loadimg"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.loadimg.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>
</application>
</manifest>
package com.itheima.loadimg;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
}
public void click(View view){
//相當消耗內存資源 根據圖片的分辨率而定
// Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg");
// iv.setImageBitmap(bitmap);
//1.得到屏幕的寬高信息
WindowManager wm = getWindowManager();
int screenWidth = wm.getDefaultDisplay().getWidth();
int screenHeight = wm.getDefaultDisplay().getHeight();
System.out.println("屏幕寬高:"+screenWidth+"-"+screenHeight);
//2.得到圖片的寬高。
BitmapFactory.Options opts = new Options();//解析位圖的附加條件
opts.inJustDecodeBounds = true;//不去解析真實的位圖,只是獲取這個位圖的頭文件信息
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg", opts);
int bitmapWidth = opts.outWidth;
int bitmapHeight = opts.outHeight;
System.out.println("圖片寬高: "+bitmapWidth+"-"+bitmapHeight);
//3.計算縮放比例
int dx = bitmapWidth/screenWidth;
int dy = bitmapHeight/screenHeight;
int scale = 1;
if(dx>dy&&dy>1){
System.out.println("按照水平方法縮放,縮放比例:"+dx);
scale = dx;
}
if(dy>dx&&dx>1){
System.out.println("按照垂直方法縮放,縮放比例:"+dy);
scale = dy;
}
//4.縮放加載圖片到內存。
opts.inSampleSize = scale;
opts.inJustDecodeBounds = false;//真正的去解析這個位圖。
bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg", opts);
iv.setImageBitmap(bitmap);
}
}
創建一個圖形的拷貝
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="click"
android:text="拷貝一個位圖" />
<ImageView
android:id="@+id/iv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.copybitmap"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.copybitmap.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>
</application>
</manifest>
package com.itheima.copybitmap;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv1,iv2;
private Bitmap alterBitmap;
private Bitmap srcBmp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv1 = (ImageView) findViewById(R.id.iv1);
iv2 = (ImageView) findViewById(R.id.iv2);
//給第一個imageview默認設置一個位圖
srcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
iv1.setImageBitmap(srcBmp);
//創建原圖的一個副本。 可修改 創建的是一個空白的圖形。
alterBitmap = Bitmap.createBitmap(srcBmp.getWidth(), srcBmp.getHeight(),srcBmp.getConfig());
}
/**
* 創建原圖 bm的一個拷貝。副本
* @param view
*/
public void click(View view){
//1.準備一個畫板 在上面放上準備好的 空白的位圖
Canvas canvas = new Canvas(alterBitmap);
//2.準備一個畫筆
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//3.畫畫
Matrix m = new Matrix();
canvas.drawBitmap(srcBmp, m, paint);
iv2.setImageBitmap(alterBitmap);//把原圖的副本設置到界面上。
}
}
圖片的放大和縮小
package com.itheima.copybitmap;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv1,iv2;
private Bitmap alterBitmap;
private Bitmap srcBmp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv1 = (ImageView) findViewById(R.id.iv1);
iv2 = (ImageView) findViewById(R.id.iv2);
//給第一個imageview默認設置一個位圖
srcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
iv1.setImageBitmap(srcBmp);
//創建原圖的一個副本。 可修改 創建的是一個空白的圖形。
alterBitmap = Bitmap.createBitmap(srcBmp.getWidth()*2, srcBmp.getHeight()*2,srcBmp.getConfig());
}
/**
* 創建原圖 bm的一個拷貝。副本
* @param view
*/
public void click(View view){
//1.準備一個畫板 在上面放上準備好的 空白的位圖
Canvas canvas = new Canvas(alterBitmap);
//2.準備一個畫筆
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//3.畫畫
Matrix m = new Matrix();
m.setScale(2.0f, 2.0f);
canvas.drawBitmap(srcBmp, m, paint);
iv2.setImageBitmap(alterBitmap);//把原圖的副本設置到界面上。
}
}
圖形的旋轉和特殊效果
圖像的旋轉
package com.itheima.copybitmap;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv1,iv2;
private Bitmap alterBitmap;
private Bitmap srcBmp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv1 = (ImageView) findViewById(R.id.iv1);
iv2 = (ImageView) findViewById(R.id.iv2);
//給第一個imageview默認設置一個位圖
srcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
iv1.setImageBitmap(srcBmp);
//創建原圖的一個副本。 可修改 創建的是一個空白的圖形。
alterBitmap = Bitmap.createBitmap(srcBmp.getWidth(), srcBmp.getHeight(),srcBmp.getConfig());
}
/**
* 創建原圖 bm的一個拷貝。副本
* @param view
*/
public void click(View view){
//1.準備一個畫板 在上面放上準備好的 空白的位圖
Canvas canvas = new Canvas(alterBitmap);
//2.準備一個畫筆
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//3.畫畫
Matrix m = new Matrix();
m.setRotate(180, srcBmp.getWidth()/2, srcBmp.getHeight()/2);
canvas.drawBitmap(srcBmp, m, paint);
iv2.setImageBitmap(alterBitmap);//把原圖的副本設置到界面上。
}
}
圖形的鏡面效果
package com.itheima.copybitmap;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv1,iv2;
private Bitmap alterBitmap;
private Bitmap srcBmp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv1 = (ImageView) findViewById(R.id.iv1);
iv2 = (ImageView) findViewById(R.id.iv2);
//給第一個imageview默認設置一個位圖
srcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
iv1.setImageBitmap(srcBmp);
//創建原圖的一個副本。 可修改 創建的是一個空白的圖形。
alterBitmap = Bitmap.createBitmap(srcBmp.getWidth(), srcBmp.getHeight(),srcBmp.getConfig());
}
/**
* 創建原圖 bm的一個拷貝。副本
* @param view
*/
public void click(View view){
//1.準備一個畫板 在上面放上準備好的 空白的位圖
Canvas canvas = new Canvas(alterBitmap);
//2.準備一個畫筆
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//3.畫畫
Matrix m = new Matrix();
m.setScale(1.0f, -1.0f);
m.postTranslate(0, srcBmp.getHeight());
canvas.drawBitmap(srcBmp, m, paint);
iv2.setImageBitmap(alterBitmap);//把原圖的副本設置到界面上。
}
}
小遊戲-撕衣服
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/after" />
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
package com.itheima.play;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
// 可以修改的位圖
private Bitmap alertBitmap;
private Canvas canvas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.pre);
// 創建一個空白的原圖的拷貝
alertBitmap = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), bitmap.getConfig());
canvas = new Canvas(alertBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawBitmap(bitmap, new Matrix(), paint);
iv.setImageBitmap(alertBitmap);
iv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:// 手指按下屏幕
System.out.println("action down");
break;
case MotionEvent.ACTION_MOVE:// 手指在屏幕上移動
int x = (int) event.getX();
int y = (int) event.getY();
System.out.println("設置("+x+","+y+")透明顏色");
for(int i=-4;i<5;i++){
for(int j=-4;j<5;j++){
try{
alertBitmap.setPixel(x+i, y+j, Color.TRANSPARENT);
}catch (Exception e) {
// TODO: handle exception
}
}
}
iv.setImageBitmap(alertBitmap);
break;
case MotionEvent.ACTION_UP:// 手指離開屏幕
MediaPlayer.create(getApplicationContext(), R.raw.higirl).start();
break;
}
return true;//可以重複循環的處理事件
}
});
}
}
人臉識別
Google 自帶的api, 不好用
國內的網站:
http://www.faceplusplus.com.cn/