Java中的private潤飾符掉效了?。本站提示廣大學習愛好者:(Java中的private潤飾符掉效了?)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中的private潤飾符掉效了?正文
成績描寫
生怕年夜家都邑碰到如許的成績,一個點擊事宜屢次觸發,招致,異樣的內容提交了屢次,或許說彈出多個頁面...
onClick事宜是Android開辟中最多見的事宜。好比,一個submitButton,功效是點擊以後會提交一個定單,則普通代碼以下,個中submitOrder()函數會跳轉到下一頁停止處置 :
<code class="hljs" java=""> //代碼0 submitButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { submitOrder(); } }); </code>
正常情形下這段代碼是沒甚麼成績的,然則Android裝備的機型機能等千差萬別,假如碰著比擬卡的手機,則有能夠湧現submitOrder()函數跳轉頁面湧現延遲的景象。碰著這類景象,則用戶就很有能夠再次點擊一次,從而形成函數被挪用兩次,湧現反復定單的BUG。
普通地,碰著這景象,起首就會想到的就是在點擊以後把submitButton設置為弗成點擊:
<code class="hljs" cs=""> //代碼1 submitButton.setClickable(false); //或許 submitButton.setEnabled(false); </code>
此辦法也確切有用,不外假如submitOrder()辦法沒有勝利,須要再次提交定單時又須要再反復把submitButton設置為可點擊狀況。假如相似的button比擬多時,就顯得比擬費事、凌亂。
計劃
自界說一個NoDoubleClickListener,繼續自OnClickListener:
<code class="hljs" java=""> //代碼2 public abstract class NoDoubleClickListener implements OnClickListener { public static final int MIN_CLICK_DELAY_TIME = 1000; private long lastClickTime = 0; @Override public void onClick(View v) { long currentTime = Calendar.getInstance().getTimeInMillis(); if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME) { lastClickTime = currentTime; onNoDoubleClick(v); } } }</code>
應用辦法—— 給submitButton設置點擊事宜時用NoDoubleClickListener取代OnClickListener,而且完成辦法onNoDoubleClick取代onClick便可,像如許:
<code class="hljs" java=""> //代碼3 submitButton.setOnClickListener(new NoDoubleClickListener() { @Override public void onNoDoubleClick(View v) { submitOrder(); } }); </code>
道理:
很簡略,見代碼……
就是用onNoDoubleClick取代onClick處置詳細的操作,在onClick辦法中加一個斷定:在吸收到點擊事宜以後,先斷定一下時光,假如間隔前次處置操作缺乏MIN_CLICK_DELAY_TIME,就疏忽——即能避免誤操作的持續點擊招致反復事宜。
MIN_CLICK_DELAY_TIME可調。
優勢
利益是不消轉變原有代碼的邏輯,就只須要兩個調換:NoDoubleClickListener取代OnClickListener,onNoDoubleClick取代onClick。 代碼的構造等都不須要做轉變(**比較下面的代碼0跟代碼**3),不須要關懷處置更改button的狀況這些額定斷定邏輯,只須要存眷營業邏輯便可,簡練優雅~
��面的代碼,當我們履行了Activity的finish辦法,被延遲的新聞會在被處置之前存在於主線程新聞隊列中10分鐘,而這個新聞中又包括了Handler的援用,而Handler是一個匿名外部類的實例,其持有裡面的SampleActivity的援用,所以這招致了SampleActivity沒法收受接管,停止招致SampleActivity持有的許多資本都沒法收受接管,這就是我們常說的內存洩漏。留意下面的new Runnable這裡也是匿名外部類完成的,異樣也會持有SampleActivity的援用,也會阻攔SampleActivity被收受接管。
要處理這類成績,思緒就是不實用非靜態外部類,繼續Handler���,要末是放在零丁的類文件中,要末就是應用靜態外部類。由於靜態的外部類不會持有內部類的援用,所以不會招致內部類實例的內存洩漏。當你須要在靜態外部類中挪用內部的Activity時,我們可使用弱援用來處置。別的關於異樣也須要將Runnable設置為靜態的成員屬性。留意:一個靜態的匿名外部類實例不會持有內部類的援用。 修正後不會招致內存洩漏的代碼以下:
public class SampleActivity extends Activity {
/**
* Instances of static inner classes do not hold an implicit
* reference to their outer class.
*/
private static class MyHandler extends Handler {
private final WeakReference<SampleActivity> mActivity;
public MyHandler(SampleActivity activity) {
mActivity = new WeakReference<SampleActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
SampleActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
private final MyHandler mHandler = new MyHandler(this);
/**
* Instances of anonymous classes do not hold an implicit
* reference to their outer class when they are "static".
*/
private static final Runnable sRunnable = new Runnable() {
@Override
public void run() { /* ... */ }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Post a message and delay its execution for 10 minutes.
mHandler.postDelayed(sRunnable, 1000 * 60 * 10);
// Go back to the previous Activity.
finish();
}
}
其其實Android中許多的內存洩漏都是因為在Activity中應用了非靜態外部類招致的,就像本文提到的一樣,所以當我們應用時要非靜態外部類時要非分特別留意,假如其實例的持有對象的性命周期年夜於其內部類對象,那末就有能夠招致內存洩漏。小我偏向於應用文章的靜態類和弱援用的辦法處理這類成績。