當前位置:首頁 » 安卓系統 » android可見性

android可見性

發布時間: 2024-09-24 07:29:08

Ⅰ Android中判斷app何時啟動和關閉的技術研究

Android開發中不可避免的會遇到需要檢查app何時進入前台,何時被用戶關閉。奇怪的是,要達到這個目的並不容易。檢查app第一次啟動並不難,但要判斷它何時重新打開和關閉就沒有那麼簡單了。

這篇文章將介紹一種判斷app打開,重新打開和關閉的技術。

讓我們開始吧

判斷一個app打開和關閉的關鍵在於判斷它的activities是否正在前台顯示。讓我們先從簡單的例子開始,一個只有一個activity的app,而且不支持水平模式。這樣想要判斷app是打開還是關閉只需要檢查activity的onStart和onStop方法即可:

[Java] 純文本查看 復制代碼

@Override

protected void onStart() {

super.onStart();

// The Application has been opened!

}

@Override

protected void onStop() {

super.onStop();

// The Application has been closed!

}

上面例子的問題在於當需要支持水平模式時該方法就失效了。當我們旋轉設備時activity將會重建,onStart方法將被再次調用,這時將會錯誤的判斷為app第二次被打開。

為了處理設備旋轉的情況,我們需要增加一個校驗步驟。當activity退出時啟動一個定時器,用於判斷短時間內app的這個activity是否又被啟動,如果沒有,說明用戶真的退出了這個app,如果重新啟動了這個activity,說明用戶還逗留在這個app中。

這種校驗方式也適用於擁有多個activities的app,因為從app的一個activity跳轉到另一個activity也可以用這種校驗方式來處理。

使用這個技術我創建了一個管理類,所有的activities在可見和不可見時都會通知這個管理類。這個管理類為每個activity處理上述的校驗步驟,從而避免錯誤的檢測。它也提供了發布訂閱(觀察者)模式,任何對app啟動和關閉感興趣的模塊都可以通過它來得到對應的通知。

這個管理類的使用分為三個步驟:

1)把它添加到你的工程中

2)Activities在可見性改變的需要發送通知

app中所有activities都要增加下面的代碼,用於可見性改變時通知管理類。最好的實現方式是把這段代碼加到工程的BaseActivity中。

[Java] 純文本查看 復制代碼

@Override

protected void onStart() {

super.onStart();

AppForegroundStateManager.getInstance().onActivityVisible(this);

}

@Override

protected void onStop() {

AppForegroundStateManager.getInstance().onActivityNotVisible(this);

super.onStop();

}

3)訂閱app的前台可見性改變事件

在感興趣的模塊中訂閱app前台可見性改變事件,application類的onCreate函數是一個不錯的地方,它可以保證每次app啟動和關閉,你都能得到通知。

public class MyApplication extends Application {

@Override

public void onCreate() {

super.onCreate();

AppForegroundStateManager.getInstance().addListener(this);

}

@Override

public void onAppForegroundStateChange(AppForegroundStateManager.AppForegroundState newState) {

if (AppForegroundStateManager.AppForegroundState.IN_FOREGROUND == newState) {

// App just entered the foreground. Do something here!

} else {

// App just entered the background. Do something here!

}

}

}

進一步的思考

有一些細節需要進一步討論,下面討論的幾點針對具體的應用可以做微調。

校驗時間

校驗定時器檢查app是否真的進入後台的時間間隔是多少合適呢?上面的代碼設置為30秒,原因如下。

當你的app在運行時,可能存在第三方的activities會覆蓋全屏幕,一些常見的例子是Google應用內購買和Facebook登錄注冊頁面。這些情況下你的app都會被迫進入後台,前台用於顯示這些第三方頁面。如果把這種情況當做用戶離開了你的app,顯然是不對的。30秒超時設置就是用來避免這種情況的。例如當用戶在30秒內完成應用內購買,大部分用戶都可以做得到,那麼就不會當做用戶突然離開app了。

如果你的app不存在上述這種情況,我建議可以把你的校驗時間設置為4秒,這樣對於低配設備當屏幕旋轉重新創建activity的時間間隔是合適的。

CPU休眠

可能存在的問題是當用戶關閉app或者app仍處於前台時用戶鎖屏了,這時CPU可能不會等到定時器檢測就休眠了。為了保證這種情況下定時器能夠正常檢測用戶退出app,我們需要持有wakelock防止CPU休眠直到app關閉事件被確認。實踐中相比使用wakelock,這種情況並不算問題。

判斷app是如何啟動的

現在我們已經知道如何檢測app何時啟動和關閉,但我們不知道app是如何啟動的。是用戶點擊通知欄消息?還是點擊一個鏈接?亦或是他們直接通過桌面圖標或最近使用啟動?

跟蹤啟動機制

首先我們需要知道在哪裡檢測app是如何啟動的。基於前面一個例子我們可以列印出app何時啟動,以及如何啟動。

public class MyApplication extends Application {

public final String TAG = MyApplication.class.getSimpleName();

public enum LaunchMechanism {

DIRECT,

NOTIFICATION,

URL;

}

private LaunchMechanism mLaunchMechanism = LaunchMechanism.DIRECT;

public void setLaunchMechanism(LaunchMechanism launchMechanism) {

mLaunchMechanism = launchMechanism;

}

@Override

public void onCreate() {

super.onCreate();

AppForegroundStateManager.getInstance().addListener(this);

}

@Override

public void onAppForegroundStateChange(AppForegroundStateManager.AppForegroundState newState) {

if (AppForegroundStateManager.AppForegroundState.IN_FOREGROUND.equals(newState)) {

// App just entered the foreground.

Log.i(TAG, "App Just Entered the Foreground with launch mechanism of: " + mLaunchMechanism);

} else {

// App just entered the background. Set our launch mode back to the default of direct.

mLaunchMechanism = LaunchMechanism.DIRECT;

}

}

}

設置啟動機制

現在我們可以列印app何時啟動的機制,但我們沒有設置它。因此下一步就是在用戶通過鏈接或者通知啟動app時我們記下它。如果沒有通過這兩種方式設置過,說明用戶是通過點擊app圖標啟動的。

跟蹤鏈接點擊事件

為了跟蹤用戶點擊鏈接打開app,你需要找到代碼中處理鏈接的地方,並加入下面的代碼來跟蹤啟動機制。要確保這些代碼在activity的onStart()函數之前調用。在哪些地方加入下面的代碼取決於你的app架構了。

getApplication().setLaunchMechanism(LaunchMechanism.URL);
1
跟蹤通知事件

不幸的是跟蹤通知點擊需要更多技巧,通知顯示後,點擊它將會打開之前綁定好的一個PendingIntent,這里的技巧是為通知的所有PendingIntents添加一個標識表明是由通知發出的。

例如當為通知創建PendingIntent時為每個intent添加如下代碼:

public static final String EXTRA_HANDLING_NOTIFICATION = "Notification.EXTRA_HANDLING_NOTIFICATION";

// Put an extra so we know when an activity launches if it is a from a notification

intent.putExtra(EXTRA_HANDLING_NOTIFICATION, true);

到這一步我們需要做的就是在每個activity(統一在BaseActivity中添加)中檢查這個標識。當識別到這個標識時說明是從通知啟動的,這時可以把啟動機制設置為通過通知。這一步應該在onCreate中處理,這樣在app啟動到前台之前就設置好了(會觸發啟動機制的列印)。

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Intent intent = getIntent();

if (intent != null && intent.getExtras() != null) {

// Detect if the activity was launched by the user clicking on a notification

if (intent.getExtras().getBoolean(EXTRA_HANDLING_NOTIFICATION, false)) {

// Notify that the activity was opened by the user clicking on a notification.

getApplication().setLaunchMechanism(LaunchMechanism.NOTIFICATION);

}

}

}

Ⅱ Android開發中如何檢測View的可見性

if(view.getVisibility()==View.VISIBLE){
說明view可見
}
if(view.getVisibility()==View.INVISIBLE){
說明view不可見
}

熱點內容
嵌入式資料庫java 發布:2024-09-24 11:09:13 瀏覽:830
流量測速緩存 發布:2024-09-24 11:08:36 瀏覽:618
編程用電腦嗎 發布:2024-09-24 11:07:05 瀏覽:829
java資料庫連接mysql 發布:2024-09-24 11:07:01 瀏覽:274
扣扣為什麼每次登錄要輸密碼 發布:2024-09-24 10:57:32 瀏覽:108
minecraft伺服器vps如何使用 發布:2024-09-24 10:52:31 瀏覽:189
反恐行動終結腳本怎麼弄 發布:2024-09-24 10:48:03 瀏覽:621
c語言有什麼好處 發布:2024-09-24 10:47:14 瀏覽:199
wcf上傳文件 發布:2024-09-24 10:37:06 瀏覽:570
android數據存儲方法 發布:2024-09-24 10:35:45 瀏覽:234