2012-05-15 20 views
23

Tôi cố gắng để tự động chụp và đăng nhập các sự kiện vòng đời sử dụng Android ActivityLifecycleCallbacks, tuy nhiên tài liệu về vấn đề này là khan hiếm, để nói rằng ít nhất:Tự động ghi nhật ký sự kiện vòng đời Android bằng ActivityLifecycleCallbacks?

public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback) 

Tôi không muốn phải mở rộng các lớp Hoạt động hoặc ghi đè các phương thức vòng đời hiện có (onCreate, onResume, etc ...) Tôi đang tìm kiếm một lớp riêng biệt lắng nghe những sự kiện này và hành động tương ứng.

Có ai có bất kỳ kinh nghiệm nào trong lĩnh vực này hoặc có liên kết đến tài liệu hoặc hướng dẫn vững chắc về cách hoạt động này không? Cụ thể, cách đăng ký ActivityLifecycleCallbacks và cách xử lý chúng?

+1

UPDATE: Các API chuẩn hiện nay đã được khoảng dài đủ rằng cuộn của riêng bạn của ClarkXP là quá mức cần thiết cho hầu hết các ứng dụng. Thay vào đó, hãy xem câu trả lời của @ Jeroen. Tôi tóm tắt/làm rõ là "Trong lớp gọi lại của bạn (có' triển khai Application.ActivityLifecycleCallbacks'), trong hàm tạo của nó làm 'getApplication(). RegisterActivityLifecycleCallbacks (this);' Nếu lớp của bạn có 'onCreate' hoặc' init' hoặc phương thức tương tự chạy khi cá thể trở thành hoạt động, đặt dòng đó ở đó chứ không phải trong hàm tạo (vì lớp có lẽ không muốn nhận các cuộc gọi lại cho đến khi nó hoàn toàn sẵn sàng). " – ToolmakerSteve

Trả lời

29

Tôi đã thực hiện riêng của mình là Application.ActivityLifecycleCallbacks. Tôi đang sử dụng SherlockActivity, nhưng đối với lớp Hoạt động bình thường có thể hoạt động.

Thứ nhất, tôi là tạo ra một giao diện mà có tất cả các phương pháp để theo dõi các hoạt động chu kỳ:

public interface ActivityLifecycleCallbacks{ 
    public void onActivityStopped(Activity activity); 
    public void onActivityStarted(Activity activity); 
    public void onActivitySaveInstanceState(Activity activity, Bundle outState); 
    public void onActivityResumed(Activity activity); 
    public void onActivityPaused(Activity activity); 
    public void onActivityDestroyed(Activity activity); 
    public void onActivityCreated(Activity activity, Bundle savedInstanceState); 
} 

Thứ hai, tôi thực hiện giao diện này trong lớp ứng dụng của tôi:

public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{ 

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

    @Override 
    public void onActivityStopped(Activity activity) { 
     Log.i("Tracking Activity Stopped", activity.getLocalClassName()); 

    } 

    @Override 
    public void onActivityStarted(Activity activity) { 
     Log.i("Tracking Activity Started", activity.getLocalClassName()); 

    } 

    @Override 
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 
     Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityResumed(Activity activity) { 
     Log.i("Tracking Activity Resumed", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityPaused(Activity activity) { 
     Log.i("Tracking Activity Paused", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityDestroyed(Activity activity) { 
     Log.i("Tracking Activity Destroyed", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 
     Log.i("Tracking Activity Created", activity.getLocalClassName()); 
    } 
} 

Thứ ba, tôi đang tạo một lớp mở rộng từ SherlockActivity:

public class MySherlockActivity extends SherlockActivity { 

    protected MyApplication nMyApplication; 

    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     nMyApplication = (MyApplication) getApplication(); 
     nMyApplication.onActivityCreated(this, savedInstanceState); 
    } 

    protected void onResume() { 
     // TODO Auto-generated method stub 
     nMyApplication.onActivityResumed(this); 
     super.onResume(); 

    } 

    @Override 
    protected void onPause() { 
     // TODO Auto-generated method stub 
     nMyApplication.onActivityPaused(this); 
     super.onPause(); 
    } 

    @Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     nMyApplication.onActivityDestroyed(this); 
     super.onDestroy(); 
    } 

    @Override 
    protected void onStart() { 
     nMyApplication.onActivityStarted(this); 
     super.onStart(); 
    } 

    @Override 
    protected void onStop() { 
     nMyApplication.onActivityStopped(this); 
     super.onStop(); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     nMyApplication.onActivitySaveInstanceState(this, outState); 
     super.onSaveInstanceState(outState); 
    } 
} 

Thứ tư, tất cả các lớp tha t mở rộng từ SherlockActivity, tôi thay thế cho MySherlockActivity:

public class MainActivity extends MySherlockActivity{ 

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

} 

Bây giờ, trong logcat bạn sẽ thấy các bản ghi được lập trình trong việc thực hiện giao diện thực hiện trong MyApplication.

CẬP NHẬT

thực hiện này đã được thử nghiệm từ API Level 9 (Gingerbread), API Level 12 (Honeycomb) và API Cấp 17 (Jelly Bean) và hoạt động tốt. Có thể hoạt động trong các phiên bản cũ hơn của Android.

+2

Để hoàn thành, hãy xem xét thêm onActivityRestart() vào giao diện và các phương thức thích hợp cho MyApplication và MySherlockActivity. Tôi nhận ra rằng phương thức này không phải là một phần của ActivityLifecycleCallbacks của Android, nhưng onRestart _is_ một phần của vòng đời của Activity. –

+1

Hữu ích cho các thiết bị cũ hơn. LƯU Ý: Nếu bạn (bất kỳ ai) đang tìm cách sử dụng Application.ActivityLifecycleCallbacks, thì bạn đang giả định một API đủ gần đây và bạn có thể bỏ qua giao diện tùy chỉnh và mở rộng Hoạt động. Chỉ cần làm (1) phần mã đầu tiên, trong đó cho thấy làm thế nào để mở rộng một lớp (trong trường hợp này là Application) để thực hiện giao diện, nhưng thực hiện các ứng dụng Application.ActivityLifecycleCallbacks'. Và (2) 'getApplication(). RegisterActivityLifecycleCallbacks (this);' trong hàm tạo lớp gọi lại của bạn hoặc onCreate. – ToolmakerSteve

39

tôi không có bất kỳ kinh nghiệm trực tiếp nhưng xét từ API bạn chỉ có thể viết lớp của riêng bạn mà thực hiện giao diện Application.ActivityLifecycleCallbacks và đăng ký lớp trên được cung cấp Application dụ lớp

getApplicaton().registerActivityLifecycleCallbacks(yourCustomClass); 

Lớp này sẽ nhận được cùng một callbacks như các hoạt động cá nhân của bạn. Chúc may mắn.

PS. Đây là cấp API 14 btw, vì vậy nó sẽ không hoạt động trên các điện thoại cũ.

+1

@ClarkXP có nhưng liên kết kế thừa quá mạnh đối với lớp ứng dụng. Đây không phải là mô-đun đủ để được biến thành một lib. – Snicolas

+0

Để làm rõ dòng 'register': Trong lớp gọi lại của bạn (có' hiện thực Application.ActivityLifecycleCallbacks'), trong hàm tạo của nó làm 'getApplication(). RegisterActivityLifecycleCallbacks (this);' Nếu lớp của bạn có 'onCreate' hoặc' init 'hoặc phương thức tương tự chạy khi cá thể trở thành hoạt động, đặt dòng đó ở đó chứ không phải trong hàm tạo (vì lớp có lẽ không muốn nhận các cuộc gọi lại cho đến khi nó hoàn toàn sẵn sàng). – ToolmakerSteve

+3

Điều này có vẻ hoàn hảo với tôi nhưng tôi tự hỏi nơi để gọi unregisterActivityLifecycleCallbacks() phương pháp. Là nó không cần thiết? – Amit

3

Hãy thử điều này: http://engineering.meetme.com/2015/04/android-determine-when-app-is-opened-or-closed/#comment-202

Nó đưa ra AppForegroundStateManager mà từng hoạt động báo cáo thông qua onStop()onStart() chức năng của nó như thế này:

@Override 
protected void onStart() { 
    super.onStart(); 
    AppForegroundStateManager.getInstance().onActivityVisible(this); 
} 

@Override 
protected void onStop() { 
    AppForegroundStateManager.getInstance().onActivityNotVisible(this); 
    super.onStop(); 
} 

lớp Application của bạn thực hiện một người biết lắng nghe như thế này:

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.equals(newState)) { 
      // App just entered the foreground. Do something here! 
      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; 
     } 
    } 
} 

Nó cũng bao gồm các mẹo và thủ thuật để xác định ho w ứng dụng đã được mở - từ thông báo, URL mở ứng dụng của bạn hoặc trực tiếp từ menu Ứng dụng. Này được thực hiện thông qua một Enum trong lớp Application:

public enum LaunchMechanism { 
    DIRECT, 
    NOTIFICATION, 
    URL, 
    BACKGROUND 
} 

private LaunchMechanism mLaunchMechanism = LaunchMechanism.DIRECT; 

public void setLaunchMechanism(LaunchMechanism launchMechanism) { 
    mLaunchMechanism = launchMechanism; 
} 

Thực hiện của chúng tôi điều này, chúng ta có cờ khi chúng tôi bắt đầu một hoạt động mà sẽ tung ra một hoạt động của bên thứ ba, như nếu người dùng thực hiện cuộc gọi điện thoại từ ứng dụng của chúng tôi hoặc nếu trình duyệt được khởi chạy. Trong hoạt động ra mắt của onStop() chúng tôi sau đó làm một kiểm tra như thế này để chỉ báo cáo hoạt động không phải là khả năng hiển thị khi những lá cờ là sai:

if(!flag_userLaunchedThirdPartyActivity){ 
    AppForegroundStateManager.getInstance().onActivityNotVisible(this); 
    } 

Đối với kiểm tra hay không ứng dụng đi vào nền - ví dụ như khi thiết bị của màn hình đi tối hoặc người dùng nhận được một cú điện thoại - nó hoạt động như thế này:

public static boolean isApplicationGoingToBackground(final Context context) { 

    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    List<RunningTaskInfo> tasks = am.getRunningTasks(1); 
    if (!tasks.isEmpty()) { 
     ComponentName topActivity = tasks.get(0).topActivity; 
     if (!topActivity.getPackageName().equals(context.getPackageName())) { 
      setLaunchMechanism(LaunchMechanism.BACKGROUND); 
      return true; 
     } 
    } 

    setLaunchMechanism(LaunchMechanism.DIRECT); 
    return false; 
} 

giải pháp này không phụ thuộc vào mức độ API, vì vậy nó sẽ làm việc tất cả các cách trở lại mức API 1.

0
@Override 
public void onCreate() { 
    super.onCreate(); 
    registerActivityLifecycleCallbacks(MyApplication.this/*(Your Application Name)*/); 

// registerActivityLifecycleCallbacks (MyApplication.this/(Tên ứng dụng của bạn)/ // chỉ thêm dòng này trên lớp ứng dụng tất cả các công trình tốt

}