成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

高質量 Android 開發框架 LoonAndroid 詳解

開發 架構
整個框架式不同于androidannotations,Roboguice等ioc框架,這是一個類似spring的實現方式。在整應用的生命周期中找到切入點,然后對activity的生命周期進行攔截,然后插入自己的功能。

整個框架式不同于androidannotations,Roboguice等ioc框架,這是一個類似spring的實現方式。在整應用的生命周期中找到切入點,然后對activity的生命周期進行攔截,然后插入自己的功能。

框架的說明

如果你想看ui方面的東西,這里沒有,想要看牛逼的效果這里也沒有。這只是純實現功能的框架,它的目標是節省代碼量,降低耦合,讓代碼層次看起來更 清晰。整個框架一部分是網上的,一部分是我改的,為了適應我的編碼習慣,還有一部分像orm完全是網上的組件。在此感謝那些朋友們。整個框架式的初衷是為 了偷懶,之前都是一個功能一個jar,做項目的時候拉進去,這樣對于我來說依然還是比較麻煩。最后就導致我把所有的jar做成了一個工具集合包。有很多框 架都含有這個工具集合里的功能,這些不一定都好用,因為這是根據我個人使用喜歡來實現的,如果你們有自己的想法,可以自己把架包解壓了以后,源碼拉出來改 動下。目前很多框架都用到了注解,除了androidannotations沒有入侵我們應用的代碼以外,其他的基本上都有,要么是必須繼承框架里面的 activity,要么是必須在activity的oncreat里面調用某個方法。整個框架式不同于 androidannotations,Roboguice等ioc框架,這是一個類似spring的實現方式。在整應用的生命周期中找到切入點,然后對 activity的生命周期進行攔截,然后插入自己的功能。

如果需要混淆 第一步 你要先引入你得架包 -libraryjars   libs/android-support-v4.jar -libraryjars   libs/loonandroid.jar 第二步 你要保證注解在代碼優化的時候不能被刪除掉 -keepattributes Signature -keepattributes Annotation第三步 support4 要排除掉 -dontwarn android.support.v4.**
-keep class android.support.v4.** { ; }
-keep interface android.support.v4.app.
* { ; }
-keep public class * extends android.support.v4.
*
-keep public class * extends android.app.Fragment 第四步 只要使用了注解的包名 全部排除掉 -dontwarn xxx.**
-keep class xxx.** { ; }
其中XXX替換成你使用了注解的包名第五步 保證R不被混淆 -keep class *
.R$* {
*;
} 即OK

框架的主要功能

其中分為以下幾種:

  • 自動注入框架(只需要繼承框架內的application既可)

  • 圖片加載框架(多重緩存,自動回收,最大限度保證內存的安全性)

  • 網絡請求模塊(繼承了基本上現在所有的http請求)

  • eventbus(集成一個開源的框架)

  • 驗證框架(集成開源框架)

  • json解析(支持解析成集合或者對象)

  • 數據庫(不知道是哪位寫的 忘記了)

  • 多線程斷點下載(自動判斷是否支持多線程,判斷是否是重定向)

  • 自動更新模塊

  • 一系列工具類

一 自動注入框架

1 無需繼承任何BaseActivity

舉例:普通activity

  1. public class FourActivity extends Activity { 
  2.  
  3.        View xx; 
  4.  
  5.        @Override 
  6.        protected void onCreate(Bundle savedInstanceState) { 
  7.            super.onCreate(savedInstanceState); 
  8.            setContentView(R.layout.activity_main4); 
  9.            xx = find......; 
  10.            //--------------------------------------------------------- 
  11.            組件的初始化 
  12.            //--------------------------------------------------------- 
  13.        } 
  14.    } 

這其中我們會耗費大量的代碼或者重復性的去些一些代碼。特別是布局比較復雜的情況下。

如果用框架

  1. @InjectLayer(R.layout.activity_main3) 
  2. public class ThirdActivity extends Activity { 
  3.     @InjectView 
  4.     View xx; 

即可

像軟件的說明頁面,就是單純的展示一個布局,那么就是

  1. @InjectLayer(R.layout.activity_main3) 
  2. public class ThirdActivity extends Activity { 

即可

整個ioc框架不需要你繼承任何的acitivity,這樣就保證了不會在你的代碼結構層次上造成影響,因為有的時候你需要自己的BaseActivity來實現你公用的功能。

2 支持子父布局

這種情況下,對于一般的框架來說,做法有以下幾種:

  • ActivityGroup  一般的ioc框架都需要繼承框架內的activity,activitygroup會讓很多框架用不了,現在ActivityGroup也是不提倡的了。

  • BaseActivity 一般的Ioc框架會需要你的BaseActivity 去繼承框架內的activity

  • 中間用fragment 這樣的情況也一樣,你的FragmentActivity必須繼承它的activity才能實現ioc框架功能。對于這個框架來說很容易實現

1 ActivityGroup  你不需要繼承任何activity 和普通activity 實現方式(如上面的例子)

2 BaseActivity

見代碼:

首先是BaseActivity        @InjectPLayer(R.layout.activity_com)        public class BaseActivity extends Activity {}

其中R.layout.activity_com是包括上下導航的布局,中間是一個view子activity只需要這么寫即可

    @InjectLayer(value = R.layout.activity_main, parent = R.id.common)
    public class MainActivity extends BaseActivity {}

當然 又會有問題了,那么我上下導航里面的點擊事件怎么綁定,怎么去初始化,難道要每一個子activity都要去寫嗎?當然不需要

  1. @InjectPLayer(R.layout.activity_com) 
  2.   public class BaseActivity extends Activity { 
  3.   @InjectInit 
  4.   private void init() { 
  5.       MeApplication.logger.s("公共類的初始化"); 
  6.   } 
  7.  
  8.   // 這里是第一種交互事件注入方式(單擊) 
  9.   @InjectMethod(@InjectListener(ids = { R.id.top, R.id.bottom }, listeners = { OnClick.class })) 
  10.   private void click2(View view) { 
  11.       Handler_TextStyle handler_TextStyle = new Handler_TextStyle(); 
  12.       switch (view.getId()) { 
  13.           case R.id.top: 
  14.               handler_TextStyle.setString("點擊了頂部按鈕(在基類中統一注冊,也可以單獨注冊)"); 
  15.               handler_TextStyle.setBackgroundColor(Color.RED, 35); 
  16.               Toast.makeText(this, handler_TextStyle.getSpannableString(), Toast.LENGTH_LONG).show(); 
  17.               break
  18.           case R.id.bottom: 
  19.               handler_TextStyle.setString("點擊了底部按鈕(在基類中統一注冊,也可以單獨注冊)"); 
  20.               handler_TextStyle.setBackgroundColor(Color.RED, 35); 
  21.               Toast.makeText(this, handler_TextStyle.getSpannableString(), Toast.LENGTH_LONG).show(); 
  22.           break
  23.           } 
  24.       } 
  25.   } 

如上 其中@InjectInit注解表示不管是在子activity還是父activity 都是在布局初始化完成以后才會調用,其先后順序是

    父布局layout->子布局layout->父布局ioc和事件綁定->子布局事件綁定。

父activity 中可以對所有的公用組件和事件進行初始化和綁定還沒完,又會有另一個問題,如果我某個頁面下導航的a按鈕和其他頁面底部a按鈕的功能不一樣 要單獨設置怎么辦。那么我們可以在子布局進行@InjectMethod和@InjectView進行事件綁定和組件注入,它們會覆蓋父類中相同id的組 件的操作以下是view注入的方法說明:

@InjectPLayer

表示是Activity的setContentView

    @InjectLayer(value = R.layout.activity_main2, parent = R.id.common, isFull = true, isTitle = true)

其中需要哪個參數就用哪個,value 是必須的 如果只有layout可以這么寫@InjectPLayer(R.layout.activity_com)。其中value 表示layout,parent表示它在父布局中所對應組件的id 如上圖中 中間顯示區域的view的id。Isfull是否全屏,默認為false.isTitle 是否有標題,默認false;

@InjectView

自動注入view注解。

基本寫法:

    @InjectView
    TextView test;

其中test表示它在xml中對應的Id為test

    @InjectView(R.id.next2)
    TextView test;

表示它在xml中對應的Id為next2

高級寫法:

    @InjectView(binders = { @InjectBinder(method = "click", listeners = { OnClick.class, OnLongClick.class }) })
    Button next, next3, next4;

其中表示對id為next,next3,next4進行注解,其中binders 表示綁定了以下事件,binders 是個數組,也就是說可以用多個InjectBinder綁定多個事件,也可以用listeners = { OnClick.class, OnLongClick.class }來表示對組件注入了點擊事件和長按事件

    @InjectView(value = R.id.next2, binders = { @InjectBinder(method = "click", listeners = { OnClick.class }) })
    Button button;

對于變量名和組件id不一致的view則需要設置value Click 表示那些注入的事件觸發以后所調用的方法,其必須在當前類內。 // 支持由參數和無參數 即click(View view)或者click() 當然click名字必須對于變量注解中的method = “click”

  1.   private void click(View view) { 
  2.         switch (view.getId()) { 
  3.             case R.id.next: 
  4.             startActivity(new Intent(this, ThirdActivity.class)); 
  5.             break
  6.             ... 
  7.         } 
  8.     } 
  9.  
  10. @InjectResource 
  11.  
  12.     @InjectResource 
  13.     String action_settings; 
  14.  
  15.     @InjectResource 
  16.     Drawable ic_launcher; 
  17.  
  18. InjectResource支持string和drawable的注解 
  19.  
  20. @InjectMethod 

// 底部導航欄 子類覆蓋父類

  1. @InjectMethod(@InjectListener(ids = { R.id.bottom }, listeners = { OnClick.class, OnLongClick.class })) 
  2. private void click3(View view) { 
  3.     Handler_TextStyle handler_TextStyle = new Handler_TextStyle(); 
  4.     handler_TextStyle.setString("點擊了底部按鈕 子類覆蓋了父類"); 
  5.     handler_TextStyle.setBackgroundColor(Color.RED, 35); 
  6.     Toast.makeText(this, handler_TextStyle.getSpannableString(), Toast.LENGTH_LONG).show(); 

@InjectMethod是當我們對一個組件只需要觸發而不需要find出來的時候用到。 ids 表示綁定哪些id,listeners 表示綁定哪些事件 這兩個參數都是數組

當然 如果嫌注解字段太長,可以自己修改。這個是整個view的注入。

 

  1. @InjectInit 
  2.  
  3.     @InjectInit 
  4.     void init() { 
  5.         MeApplication.logger.s("子類的初始化"); 
  6.         test.setText("初始化完成,第一個頁面"); 
  7.     } 

這個注解你在activity中添加到任何一個方法名上,那么,當所有的layout和所有的view以及事件綁定完畢以后,會第一個調用含有這個注解的方法。它相當于oncreat

    注意:框架注解了整個activity的生命周期, @InjectOnNewIntent,@InjectPause,@InjectResume,
    @InjectRestart,@InjectStart,@InjectStop 其中OnDestroy無注解。
    如果Activity中有含有這些注解的方法 那么不同生命周期下回自動調用這些方法

二:Fragment的自動注入

  1. @Override 
  2. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
  3.     this.inflater = inflater; 
  4.     View rootView = inflater.inflate(R.layout.activity_left, container, false); 
  5.     Handler_Inject.injectView(this, rootView); 
  6.     return rootView; 

    只需要在onCreateView里面調用Handler_Inject.injectView(this, rootView);
    即可

    在fragment中除了activity的生命周期注解和@InjectLayer注解無法使用外,組件綁定和事件綁定都可以使用,@InjectBefore也可以使用

    @InjectBefore 是在組件初始化之前調用

三:圖片下載框架

    這個是圖片框架重寫了好多次了,總是有點問題,里面基本上每一段代碼都有注釋,還有一些bug,
    因為項目中用的還是這次重寫之前的。
    如果大家發現問題,記得告訴我框架中調用的方法名和參數基本上都不會變,避免替換jar導致需要改動大部分代碼。

整個圖片下載的邏輯是這樣的:

  • 1 根據url和view去調用圖片下載的方法

  • 2 從緩存去拿bitmap

  • 3 如果bitmap不為空 判斷是否針對這個url有單獨的配置 沒有則使用全局配置加載圖片

  • 4 如果bitmap為空 則開啟線程,放到本地線程池中,然后從本地文件讀取

  • 5 如果文件存在,則轉為bitmap放到緩存,然后重復2,然后9

  • 6 如果文件不存在,則開啟線程放到網絡線程池中去下載文件

  • 7 下載成功則放到本地sdcard 然后把文件轉為bitmap放到緩存,然后重復2,然后9

  • 8 下載不成功,然后重復2,然后9

  • 9 如果bitmap不為空 判斷是否針對這個url有單獨的配置 沒有則使用全局配置加載這張圖片 如果bitmap為空 則顯示失敗的默認圖

具體的流程 可以參考源碼

緩存分為三層

    第一層是LruCache(原理去百度)
    第二層是LinkedHashMap
    第三層是 view標記

    1 當LruCache中的圖片超過了規定了內存,那么從LruCache移除一個使用最少的,放到LinkedHashMap中
    2 當每一張圖片的url對應一個count,一旦加載一張圖片,那么這個url的count加1
    3 自定義AsyImageView繼承ImageView,重寫了onDetachedFromWindow方法,一旦
        AsyImageView從當前視圖移除掉會調用onDetachedFromWindow該方法,此刻該圖片所對應的url數目count減1
    4 因為listview中的imageview如果用了ViewHolder那么第3條就不適合了,此刻每一個imagview的hashCode對應一個url,
        一旦imagview更換了一個新的url,那么該imagview的hashcode上一個的引用將被移除,
        那么上一次顯示的url所對應的count將減1
    5 當LinkedHashMap超過了規定限制的時候,那么遍歷所有的count一旦count為0 則移除回收

圖片下載使用

一:必須條件

    必須在配置文件中添加配置,來打開圖片下載引擎的初始化,為了減少啟動時間,默認關閉。
    #開啟框架內置的圖片下載 如果不設置 則無法使用框架類的圖片下載
    imageload_open=true

    二:使用方法

1 普通圖片下載

    ImageDownloader.download("網絡和本地圖片鏈接",mAsyImageView);

如果需要配置bitmap的高寬

第一種方式:

    在xml布局文件中對AsyImageView的高寬進行設置

第二種方式:

全局圖片配置,所有圖片顯示默認用此配置

    GlobalConfig globalConfig = GlobalConfig.getInstance();
    globalConfig.setMaxWidth(w);

來設置

第三種

    SingleConfig config = new SingleConfig();
    config ....設置寬高
    ImageDownloader.download("網絡和本地圖片鏈接",mAsyImageView,config )

其中優先級

第三種 > 第一種 > 第二種

        其中GlobalConfig  支持的設置有高寬的設置,內存緩存的大小,默認圖片,
        下載失敗的圖片,最大緩存數目,線程池,緩存類型,顯示控制,listview得滑動監聽,圖片加載動畫
        其中SingleConfig 支持的設置有高寬的設置,默認圖片,下載失敗的圖片,下載進度,顯示控制,加載動畫

其中SingleConfig 優先于GlobalConfig

支持配置文件配置:

    mAsyImageView.setTemplate("one");
    ImageDownloader.download("url",mAsyImageView);

其中one在配置文件里面配置,這樣 不管在任何地方,只要AsyImageView.setTemplate(“one”);就可以使用名稱為one的配置了。

支持本地文件加載調用接口不變。

需要進度顯示的:

  1. SingleConfig config = new SingleConfig(); 
  2.  config.setDisplayer(new DisplayerLister() { 
  3.      @Override 
  4.      public void startLoader(AsyImageView imageView) { 
  5.          super.startLoader(imageView); 
  6.      } 
  7.      @Override 
  8.      public Bitmap finishLoader(Bitmap bitmap, AsyImageView imageView) { 
  9.          pin_progress_1.setVisibility(View.GONE); 
  10.          return bitmap; 
  11.      } 
  12.  
  13.      @Override 
  14.      public void progressLoader(int progress, AsyImageView imageView) { 
  15.          pin_progress_1.setProgress(progress); 
  16.          super.progressLoader(progress, imageView); 
  17.      } 
  18.  }); 
  19.  ImageDownloader.download("url",photo,config); 

其中url的服務器必須支持獲取文件長度

需要顯示動畫的:如果是單獨某一個圖片

  1. SingleConfig config = new SingleConfig(); 
  2.    config.setDisplayerAnimation(new FadeInAnimation()); 

如果是全局的

  1. GlobalConfig config = new GlobalConfig(); 
  2. config.setDisplayerAnimation(new FadeInAnimation()); 

其中FadeInAnimation是框架自帶的一個漸變的動畫如果需要自定義 實現DisplayerAnimation接口即可

2 listview中圖片下載

    只要在listview的注解@InjectView(isasy=true)中添加了isasy=true(默認為false)
    那么系統會自動給你注入OnScrollListener滾動事件,以便實現圖片飛行停止才加載,緩慢拖動加載的功能。如果你要實現自己的OnScrollListener

如下

 

  1.     @InjectBefore 
  2.     void test(){ 
  3.         //@InjectView(isasy=true)表示這個listview里面有網絡圖片下載,并且需要實現滑動停止才加載的功能 
  4.         //@InjectView(isasy=true)框架會給listview自動注入OnScrollListener,如果你自己也要滾動監聽 
  5.         //那么請在此配置,如下 
  6.         GlobalConfig config = GlobalConfig.getInstance(); 
  7.         config.setOnScrollLoaderListener(new MyOnScrollListener()); 
  8.         System.out.println("before"); 
  9.     } 
  10.     //必須繼承框架內的滾動監聽 
  11.     class MyOnScrollListener extends OnScrollLoaderListener{ 
  12.     @Override 
  13.     public void onScrollListener(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
  14.         ApplicationBean.logger.s("滾動監聽:"+firstVisibleItem); 
  15.     } 
  16.  
  17.     @Override 
  18.     public void onScrollStateChange(AbsListView view, int scrollState) { 
  19.         ApplicationBean.logger.s("滾動狀態"); 
  20.         } 
  21.     } 
  22.  
  23. @InjectBefore 表示在組件初始化以前開始調用,因為滾動監聽必須在listview被初始化之前賦值,否則無效 將默認使用框架內的滾動監聽 

3 無需顯示的圖片下載

  1. ImageDownloader.download("url"new LoaderLister() { 
  2.      @Override 
  3.      public void finishLoader(String url, File file) { 
  4.          System.out.println("下載完成"+file.getPath()); 
  5.      } 
  6.      @Override 
  7.      public void failLoader(String url) { 
  8.          System.out.println("下載失敗"); 
  9.      } 
  10.  }); 

如果需要下載進度

  1. ImageDownloader.download("url"new LoaderLister() { 
  2.  
  3.        @Override 
  4.        public void startLoader(String url) { 
  5.            System.out.println("開始下載"); 
  6.            super.startLoader(url); 
  7.        } 
  8.  
  9.        @Override 
  10.        public void finishLoader(String url, File file) { 
  11.            System.out.println("下載完成"+file.getPath()); 
  12.        } 
  13.  
  14.        @Override 
  15.        public void progressLoader(int progress) { 
  16.            System.out.println("下載進度"+progress); 
  17.            super.progressLoader(progress); 
  18.        } 
  19.    }); 

 

責任編輯:王雪燕
相關推薦

2023-07-06 14:51:30

開發高質量軟件

2011-05-31 13:43:46

外鏈

2017-07-14 09:54:47

代碼函數程序

2010-03-01 14:31:04

Java

2023-01-27 23:46:36

嵌入式軟件技巧

2021-08-08 14:26:24

SQL數據庫開發

2016-08-22 09:10:13

框架

2011-07-20 15:26:52

C++

2011-03-04 10:11:09

JavascriptAPI

2012-09-13 10:44:18

Python代碼

2023-10-15 12:07:09

2011-06-24 14:59:41

外鏈

2009-11-23 20:39:21

ibmdw敏捷開發

2020-03-12 14:03:59

工具代碼開發

2023-03-09 15:05:46

HTMLWeb 開發SEO

2011-02-16 10:38:13

Java EEJava

2015-08-03 10:40:59

程序員代碼質量Quora

2015-08-25 08:29:11

編寫高質量命名
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天操网| 亚洲精品久久久一区二区三区 | 国产一区久久久 | 一区二区三区久久 | 国产精品久久国产精品 | 亚洲视频区 | 国产一区二区影院 | 成人精品一区二区 | 久久噜噜噜精品国产亚洲综合 | 一级欧美日韩 | 天天艹 | 一区二区三区精品视频 | 五月婷婷激情网 | 欧美日韩成人 | 18av在线播放 | 天天操天天拍 | 久久精品手机视频 | 欧美日一区二区 | v片网站| 欧美中文字幕一区二区 | 精品国产91久久久久久 | 国产精品欧美一区二区 | 九九亚洲 | 亚洲图片视频一区 | 在线永久看片免费的视频 | 亚洲精品无 | www免费视频 | 欧美视频中文字幕 | 草久久久 | 日韩国产一区二区 | 激情a | 国产伦精品一区二区三区视频金莲 | 一区二区三区免费 | 亚洲一区免费视频 | 亚洲精品成人av | av大片 | 一级片在线观看 | 中文字幕视频在线观看 | 中文字幕一区二区三区精彩视频 | 日韩不卡一二区 | 99精品视频一区二区三区 |