studio - android開發




正在放棄申請嗎? (20)

Answer: (Romain Guy): The user doesn't, the system handles this automatically. That's what the activity lifecycle (especially onPause/onStop/onDestroy) is for. No matter what you do, do not put a "quit" or "exit" application button. It is useless with Android's application model. This is also contrary to how core applications work.

1: Totally exiting an application may be generally unmandatory, but it is not useless. What if windows had no exit option? System would be doggy slow as memory was full and the OS had to guess at which programs you were done with. I don't care what Romain Guy or even Larry Page and Sergey Brin say - these are unquestionable facts: Systems run slower when they have to kill tasks to get their memory before a new app can be launched. You just can't tell me that it doesn't take time to kill an app! Even the light from distant stars take time... There is some use in allowing the user to fully close apps.

2: Contrary to how core applications work? What's that supposed to mean? When I'm done running an app for now, it is no longer doing any work...It's just waiting to be killed by the OS when its memory is needed.

In summary, there is a distinct difference between minimizing and exiting, and neither pinch hits well for the other. Do we leave a screwdriver in every screw? Or a key in every door? Do we leave all of our appliances on high until the breaker blows and we need to turn on another appliance? Do we leave the dish washer full of dishes, and only take out enough each time to make room for some new dirty ones? Do we leave all the cars running in the driveway until -- oh never mind.

If the user wants to minimize an app, then the best thing is to minimize it. If a user wants to exit an app, then by all means it is best to exit.

Is it frowned on? That's Android's view - they frown on it. And many many independent rookie Android developers frown on it.

But when it comes right down to it, there is good coding and bad coding. There is good program flow models and there are bad program flow models.

Leaving programs in memory when the user knows they are done with them simply is not good program flow. It serves absolutely no purpose whatsoever, and it slows things down when launching new apps or when running apps allocate more memory.

It is sort of like your car: There are times when you leave it running, like stopping at a stop light, or perhaps the fast food drive through, or stopping at the ATM. But there are other situations where you do want to shut it off - like when you get to work, or the grocery store or even home.

Similarly, if you're playing a game and the phone rings, yes. Pause the game and keep it running. But if the user is done with the game for a while, then by all means let them exit.

The exit button on some applications should be more out in front than others. Games, for example, or programs where the user is likely to want to fully exit, should have an obvious exit. Other programs, like, perhaps, email programs, where exiting is an unlikely desire (so that it can keep checking for email) -- these programs should not waste prime control input screen space with an exit option, but for good program flow, it should have an exit option. What if someone decides they don't want their mail program trying to check email when they are in poor coverage area, or maybe in a Skype call or whatever? Let them exit the email program if they want!

Suspending and exiting are two vital tasks and neither fulfills the role of the other.

在我學習Android的嘗試中,我剛剛閱讀了以下內容

問題: 用戶是否可以選擇殺死應用程序,除非我們放入一個菜單選項來殺死它? 如果不存在這樣的選項,用戶如何終止該應用程序?

答案:(羅曼蓋伊): 用戶沒有,系統自動處理這個。 這就是活動生命週期(特別是onPause / onStop / onDestroy)的用途。 無論您做什麼,都不要放置“退出”或“退出”應用程序按鈕。 這對於Android的應用程序模型來說是沒用的。 這也與核心應用程序的工作方式相反。

嘿嘿,我在Android世界的每一步都遇到了一些問題=(

顯然,你不能在Android中退出應用程序(但Android系統可以很好地徹底銷毀你的應用程序,只要它感覺像)。 那是怎麼回事? 我開始認為編寫一個功能像“普通應用程序”的應用程序是不可能的 - 用戶可以在他/她決定這樣做時退出應用程序。 這不是應該依賴於操作系統的事情。

我試圖創建的應用程序不是Android Market的應用程序。 它不是一般公眾“廣泛使用”的應用程序,它是一個商業應用程序,將用於非常狹窄的業務領域。

我實際上非常期待為Android平台開發,因為它解決了Windows Mobile和.NET中存在的許多問題。 不過,上週對我來說有點關閉......我希望我不必放棄Android,但現在看起來不太好=(

有沒有辦法讓我真的退出應用程序?


First of all, never never never use System.exit(0). It is like making a person sleep punching him on the head!

Second: I'm facing this problem. Before sharing my solution a I want to share my thoughts.

I think that an "Exit Button" is stupid. Really really really stupid. And I think that users (consumer) that ask for an exit button for your application is stupid too. They don't understand how the OS is working and how is managing resources (and it does a great job).

I think that if you write a good piece of code that do the right things (updates, saves, and pushes) at the right moment and conditions and using the correct things (Service and Receiver) it will work pretty well and no one will complain.

But to do that you have to study and learn how things works on Android. Anyway, this is my solution to provide to users an "Exit Button".

I created an Options Menu always visible in each activity (I've a super activity that do that).

When the user clicks on that button this is what happens:

Intent intent = new Intent(this, DashBoardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

SharedPreferences settings = getSharedPreferences(getString(PREF_ID), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(FORCE_EXIT_APPLICATION, true);

  // Commit the edits!
editor.commit();
startActivity(intent);
finish();

So I'm saving in SharedPreferences that I want to kill my app, and I start an Intent. Please look at those flags; those will clear all my backstack calling my DashBoard Activity that is my "home" activity.

So in my Dashboard Activity I run this method in the onResume:

private void checkIfForceKill() {

    // CHECK IF I NEED TO KILL THE APP

    // Restore preferences
    SharedPreferences settings = getSharedPreferences(
            getString(MXMSettingHolder.PREF_ID), Context.MODE_PRIVATE);
    boolean forceKill = settings.getBoolean(
            MusicSinglePaneActivity.FORCE_EXIT_APPLICATION, false);

    if (forceKill) {

        //CLEAR THE FORCE_EXIT SETTINGS
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(FORCE_EXIT_APPLICATION, false);

        // Commit the edits!
        editor.commit();

        //HERE STOP ALL YOUR SERVICES
        finish();
    }
}

And it will work pretty well.

The only thing that I don't understand why it's happening is that when I do the last finish (and I've checked: it's following all the correct flow of onPause → onStop → onDestroy) the application is still on the recent activity (but it's blank).

It seems like the latest intent (that has started the DashboardActivity) is still in the system.

I've to dig more in order to also remove it.


As an Application in an Android context is just a bunch of vaguely related Activities, quitting an Application doesn't really make much sense. You can finish() an Activity, and the view of the previous Activity in the Activity stack will be drawn.


Every time while you move to the next page through intent, use:

`YourActivityname.this.finish()`;

例:

Intent intent = new Intent(getApplicationContext(), SMS.class);

startActivity(intent);
MainActivity.this.finish();

So that no activity will be running on background and when you want to Exit your app, use:

MainActivity.this.finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
getParent().finish();

This exiting worked like a charm for me :)


Hmmmm...

I think that you just don't see the Android app the right way. You can do something almost like what you want easily:

  • Do the app activities save/restore state like it is encouraged in the developer livecycle documentation.

  • If some login is needed at the restore stage (no login/session information available) then do it.

  • Eventually add a button/menu/timeout in which case you will do a finish() without saving the login and other session info, making implicitly the end of app session: so if the app is started/brought to front again it will start a new session.

That way you don't really care if the app is really removed from memory or not.

If you really want to remove it from memory (this is discouraged, and BTW for what purpose?) you can kill it conditionally at the end of onDestroy() with java.lang.System.exit(0) (or perhaps restartPackage(..) ?). Of course do it only in the case where you want to "really end the app", because the onDestroy() is part of the normal lifecycle of activities and not an app end at all.


I agree with Ted. I understand that exiting the application is not the "Android way", but it doesn't seem like it should be precluded. Here are three reasons why you might want a real exit to the application (not just the activity):

  1. The user might want some control over which app gets killed in the case of low memory. If important app A is running in the background, then you might like to exit app B when you are done with it so that app A doesn't get killed by the operating system.

  2. If your application has sensitive data cached in memory, you might like to kill the app so that a virus/worm/rogue app can't get at it. I know the security model is supposed to prevent that, but just in case...

  3. If your application uses resources (like network, CPU, sensors, etc.) that could adversely affect the phone, then one way of ensuring that those resources are freed up is to exit the application. I understand that well-behaved apps should free up resources when they are not needed. But again, exiting the application seems like a reasonable way of ensuring that.


I think the point is that there is no need to quit the app unless you have buggy software. Android quits the app when the user is not using it and the device needs more memory. If you have an app that needs to run a service in the background, you will likely want a way to turn the service off.

For example, Google Listen continues to play podcast when the app is not visible. But there is always the pause button to turn the podcast off when the user is done with it. If I remember correctly, Listen, even puts a shortcut in the notification bar so you can always get to the pause button quickly. Another example is an app like a twitter app for instance which constantly polls a service on the internet. These types of apps should really allow the user to choose how often to poll the server, or whether even to poll in a background thread.

If you need to have code that runs on exit, you can override onPause(), onStop(), or onDestroy() as appropriate. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle


I would consider reading "Android Wireless Application Development" published by Addison-Wesley. I am just finishing it up and it is VERY thorough.

It appears that you have some fundamental misunderstandings of the Android platform. I too was a little frustrated at first with the application life-cycle of Android apps, but after coming to a greater understanding, I have come to really enjoy this approach. This book will answer all of your questions and much more. It really is the best resource I have found for new Android developers.

Also, I think you need to let go of a line-for-line port of the existing app. In order to port your application to the Android platform, some of the application design is going to change. The application-lifecycle used is necessary as mobile devices have very limited resources relative to desktop systems and allows Android devices to run several applications in an orderly and resource-aware fashion. Do some more in depth study of the platform, and I think you will realize that what you are wanting to do is entirely feasible. Best of luck.

By the way, I am no way affiliated with Addison-Wesley or any person or organization associated with this book. After re-reading my post I feel that I came off a little fanboyish. I just really, really enjoyed it and found it extremely helpful. :)


If you have 10,20 .. multiple Activities running and you want to finish all them and exit from system.

Create a static array in application class or constants class.

Constants

public class Constants {

public static ArrayList<Activity> activities = new ArrayList<Activity>();

}

MainActivity在此數組中添加當前活動引用

activity = MainActivity.this; Constants.activities.add(activity);

public class MainActivity extends Activity {

    private ImageView imageButton;
    private Activity activity;


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

        activity = MainActivity.this;
        Constants.activities.add(activity);

        imageButton = (ImageView) findViewById(R.id.camera);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // existing app.
                if (Constants.activities != null) {
                    for (int i = 0; i < Constants.activities.size(); i++) {
                        Activity s = Constants.activities.get(i);
                        s.finish();
                    }
                }
                //super.finish();
                finish();
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(1);
            }
        });
    }
}

In any case, if you want to terminate your application you can always call System.exit(0);


The Android application life cycle is designed for mobile phone users, not computer users.

The app life-cycle is the brutally simplistic paradigm required to turn a Linux server into a consumer appliance.

Android is Java over Linux, a real cross-platform server OS. That is how it spread so quickly. The app life-cycle encapsulates the underlying reality of the OS.

To mobile users, apps are just installed or not installed. There is no concept of running or exiting. In fact, app processes are meant to run until the OS releases them for their held resources.

Since this is , anyone reading this is a computer user and must turn off 90% of their knowledge to understand the mobile app lifecycle.


The Linux kernel has a feature called Out-of-memory killer (as mentioned above, the policies are configurable at the userspace level as well as the kernel is not an optimal one, but by no means unnecessary).

And it is heavily used by Android:

Some userspace apps are available to assist with these kill apps, for example:


When I conceive an application in Android, I see it this way:

  • You are working with your application
  • The phone rang
  • You take the call
  • At the end of the call, you come back to your application at the same place you were

To do that, you only need the Back button or the Home button of your phone (either by short or long press) and the notification bar.

When I exit my application, I only use the Back button until I am out of it or the Home button.

That's how most of the applications are conceived I think. But if I need some sort of session or connection, I made it clear to the user with a login/logout button and notification (title bar or anything else). This is a rather different style than the pure "exit" style application.

On PCs, you have a multi-GUI desktop, and on Android, you obviously have multi-tasks, but you only display one app at a time (I don't consider widgets here ^^). And on a mobile phone, at anytime, you could have a notification for something more important than what you are doing.

So the whole concept of an application rely on something different that "enter application - work - exit application".


Without an exit function for the application developer to kill their own application it is very bad design.

My application needs to allow the user to dynamically change data dynamically during runtime and the user needs to restart my application to make the change effect, but Android did not allow my application restart by itself. Android OS has a very bad design application life cycle.


不要將您的應用程序視為單一應用程序。 這是一組UI屏幕,用戶可以與通過Android服務提供的“應用程序”和“功能”進行交互。

不知道你的神秘應用程序“做什麼”並不重要。 讓我們假設它通過一些超級安全的公司Intranet,執行一些監控或交互並保持登錄狀態,直到用戶“退出應用程序”。 由於您的IT部門對其進行命令控制,因此用戶必須非常清楚其何時處於Intranet或Intranet之外。 因此,你對使用者“退出”很重要。

這很簡單。 製作一項服務,在通知欄中發出持續通知,說明“我在內部網或正在運行”。 讓該服務執行您的應用程序所需的所有功能。 讓綁定到該服務的活動允許您的用戶訪問他們需要與您的“應用程序”交互所需的一些UI。 並有一個Android菜單 - >退出(或註銷,或其他)按鈕,告訴服務退出,然後關閉活動本身。

對於所有意圖和目的而言,這正是你所說的你想要的。 完成Android的方式。 看看Google Talk或谷歌地圖導航這個“退出”的例子是可能的心態。 唯一的區別是,如果用戶想要恢復應用程序,按下退出按鈕就可能讓UNIX進程處於等待狀態。 這與現代操作系統並沒有什麼不同,它將最近訪問過的文件緩存在內存中。 在你退出windows程序之後,它所需要的大部分資源仍然在內存中,等待被其他資源替換時,因為它們已經被加載,因此不再需要它們。 Android是同樣的事情。

我真的沒有看到你的問題。


博客文章何時在Android應用程序中包含退出按鈕(提示:從不)向我們解釋了這一點, 遠遠超出我的想像。 我希望每個Android開發者都已經閱讀過它。

摘錄:

根據我的經驗,用戶真正想要的是: 確保應用程序停止消耗資源(電池,CPU週期,數據傳輸等)的明確方法。

許多用戶認為退出按鈕實現了這一要求並要求添加它。 開發商希望取悅他們的用戶,並有意添加一個。 此後不久,他們都失敗了。

  • 在大多數情況下,退出按鈕只需調用Activity.finish() 。 這完全等同於點擊後退按鈕。 究竟。 服務繼續運行,輪詢不斷發生。 用戶可能認為他們已經殺死了應用程序,但他們沒有,很快他們會更加惱火。
  • 退出行為現在不明確。 您的退出按鈕是否應該關閉活動,還是應該停止所有關聯的服務,接收器和警報? 應該做什麼? 如果他們碰到Home,會發生什麼? 如果你的應用有一個小部件會發生什麼? 退出按鈕是否應該停止更新?

The solution is to make the back button behave as you'd expect the exit button to. Better yet, simply stop consuming resources whenever the app isn't visible.

Go ahead and read the complete article.


我只想在這里為這個主題的未來讀者添加更正。 這種特殊的細微差別已經逃脫了我很長一段時間的理解,所以我想確保你們沒有犯同樣的錯誤:

如果您在堆棧上有多個活動, System.exit()不會System.exit()您的應用程序。 實際發生的情況是該進程被終止並立即重新啟動 ,並且在堆棧上的活動較少。 當您的應用程序被強制關閉對話框殺死時,或者甚至當您嘗試從DDMS中終止進程時,也會發生這種情況。 就我所知,這是一個完全沒有記錄的事實。

簡短的回答是,如果你想退出你的應用程序,你必須跟踪堆棧中的所有活動,並在用戶想要退出時finish()所有這些活動(並且不可以,無法迭代活動堆棧,所以你必須自己管理所有這些)。 即使這並沒有真正殺死這個進程或任何你可能有的懸掛引用。 它只是完成了活動。 另外,我不確定Process.killProcess(Process.myPid())是否可以更好地工作。 我沒有測試過它。

另一方面,如果您的活動仍然在您的堆棧中仍然存在,還有另一種方法可以使您的工作變得非常容易: Activity.moveTaskToBack(true)僅會簡化後台進程並顯示主屏幕。

漫長的回答涉及對這種行為背後的哲學的解釋。 這一哲學誕生於許多假設:

  1. 首先,這只發生在你的應用程序處於前台時。 如果它在後台,該進程將會終止。 但是,如果它處於前台,操作系統會假定用戶想要繼續做他/她正在做的事情。 (如果你試圖從DDMS中殺死進程,你應該首先點擊主頁按鈕,然後殺死它)
  2. 它還假定每項活動都獨立於所有其他活動。 這通常是正確的,例如在您的應用程序啟動瀏覽器活動的情況下,該活動完全獨立並且不是由您編寫的。 瀏覽器活動可能會或可能不會在同一個任務上創建,具體取決於其清單屬性。
  3. 它假定你的每一項活動都是完全自力更生的,並且可以立即通知被殺死/恢復。 (我寧願不喜歡這個特定的假設,因為我的應用程序有很多依賴大量緩存數據的活動,在onSaveInstanceState期間太大而無法高效地序列化,但是whaddya會這麼做?)對於大多數寫得很好的Android應用程序,這應該是真實的,因為你永遠不知道你的應用何時會在後台被殺掉。
  4. 最後一個因素並不是一個假設,而是操作系統的一個限制: 明確殺死應用程序與應用程序崩潰相同,也與Android殺死應用程序以回收內存相同。 這最終導致我們的coup de grace:由於Android無法確定應用程序是否在後台退出或崩潰或被殺死,它假定用戶想要返回他們離開的位置,並且ActivityManager重新啟動該進程。

當你考慮這個問題時,這對平台是適合的。 首先,這正是當進程在後台被終止並且用戶返回時發生的情況,所以需要在停止的地方重新啟動。 其次,這是應用程序崩潰並顯示可怕的強制關閉對話框時發生的情況。

假設我希望我的用戶能夠拍照並上傳照片。 我從我的活動中啟動相機活動,並要求它返回圖像。 相機被推到我當前任務的頂部(而不是在自己的任務中創建)。 如果相機出現錯誤並且崩潰,是否會導致整個應用程序崩潰? 從用戶的角度來看,只有相機失敗了,他們應該返回到以前的活動。 所以它只是重新啟動堆棧中所有相同的活動,減去相機的過程。 由於你的活動應該設計成能夠在帽子下被殺死和恢復,這應該不成問題。 不幸的是,並不是所有的應用程序都可以這樣設計,所以無論Romain Guy或其他人告訴你什麼,這對我們很多人來說都是一個問題。 所以,我們需要使用解決方法。

所以,我最後的建議是:

  • 不要試圖殺死這個過程。 在所有活動上調用finish()或調用moveTaskToBack(true)
  • 如果你的進程崩潰或被殺,並且如果像我一樣,你需要內存中現在丟失的數據,則需要返回到根活動。 為此,您應該使用包含Intent.FLAG_ACTIVITY_CLEAR_TOP標誌的Intent調用startActivity()
  • 如果你想從Eclipse DDMS的角度殺死你的應用程序,最好不要在前台,否則它會重新啟動。 您應該首先按下主頁按鈕, 然後終止該過程。

我的所有應用程序都退出了按鈕......我經常從用戶那裡得到積極的評論。 我不在乎平台的設計是否應用程序不需要它們。 說“不要把它們放在那裡”有點荒謬。 如果用戶想要退出......我向他們提供訪問來做到這一點。 我不認為這會降低Android的運作方式,似乎是一種很好的做法。 我了解生命週期......我的觀察一直認為,Android在處理它方面做得併不好......這是一個基本事實。


這個爭論歸結為開發人員是否知道最好或用戶是否知道最好的古老問題。 人類因素的各個領域的專業設計師每天都在為此而鬥爭。

Ted指出,市場上下載量最大的應用程序之一就是'App Killer'。 人們在退出申請時會得到一點額外的血清素。 他們習慣於使用台式機/筆記本電腦。 它使物體快速移動。 它使處理器保持冷靜並且風扇不會打開。 它使用更少的電力。

當你認為移動設備是一艘小得多的船,那麼你可以特別欣賞他們“拋棄你不再需要的東西”的動機。 現在,Android的開發人員已經推斷操作系統知道最好,而退出應用程序是古董。 我全心全意地支持這一點。

不過,我也相信,即使這種挫敗感是由於他們自己的無知,你也不應該讓使用者感到沮喪。 因此,我得出結論認為,'退出'選項是很好的設計,即使它主要是一個安慰劑按鈕,只不過是關閉視圖而已。


這是一個有趣和有見地的討論,有這麼多的專家參與。 我覺得這篇文章應該從Android開發主網站中回放,因為它確實圍繞著Android OS的核心設計之一。

我也想在這裡添加我的兩分錢。

到目前為止,我一直對Android處理生命週期事件的方式印象深刻,將類似於網絡的體驗概念帶入本地應用程序。

說完我仍然認為應該有一個Quit按鈕。 為什麼? ......不適合我或特德或任何這裡的技術大師,但僅限於滿足最終用戶需求。

雖然我不是Windows的忠實粉絲,但早就回到他們介紹了大多數最終用戶習慣使用的概念(X按鈕)......“我想在'我'想要退出時運行一個小部件”。

這並不意味著某人(操作系統,開發人員?)會根據自己的判斷來處理該問題......它僅僅意味著“我習慣於在哪裡使用我的Red X按鈕”。 我的行為應該類似於'按下按鈕結束呼叫','按下按鈕關閉設備'等,等等......這是一種感知。 它本身就令我滿意,因為我的行為確實達到了目的。

即使開發人員可以使用此處給出的建議來欺騙此行為,但仍然存在這樣的看法,即應用程序應該完全停止運行(現在),由最終用戶根據需要提供獨立,可信和中立的來源(OS)。





android