fields) {
64 | if (args == null) {
65 | args = new Bundle();
66 | }
67 | BaseFragment topFragment = mFragmentStackManager.top();
68 | mFragmentStackManager.push(cls, args, fields);
69 | }
70 |
71 | public void popBackStack(int requestCode, int resultCode, Intent data) {
72 | mFragmentStackManager.pop(requestCode, resultCode, data);
73 | }
74 |
75 | public void popBackStack() {
76 | mFragmentStackManager.pop(-100, -100, null);
77 | }
78 |
79 | public void clearBackStack() {
80 | mFragmentStackManager.clear();
81 | }
82 |
83 |
84 | public void addContent() {
85 | addContent(-1);
86 | }
87 |
88 | public BaseFragment top() {
89 | return mFragmentStackManager.top();
90 | }
91 |
92 | protected int size() {
93 | return mFragmentStackManager.size();
94 | }
95 |
96 | public void addContent(int isDefaultTabs) {
97 | mFragmentStackManager.push(mFragmentCls, mArgs, fragmentFields);
98 | }
99 |
100 | public BaseFragment getCurrentFragment() {
101 | return top();
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/utils/Util4Common.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.utils;
2 |
3 | import android.view.View;
4 | import android.view.ViewParent;
5 |
6 | import java.lang.reflect.Field;
7 |
8 | /**
9 | * Created by yuchengluo on 2015/6/26.
10 | */
11 | public class Util4Common {
12 | public static boolean findView(View viewParent, Object findView) {
13 | if (viewParent == null || findView == null) {
14 | return false;
15 | }
16 |
17 | if (findView == viewParent) {
18 | return true;
19 | }
20 |
21 | boolean result = false;
22 | if (findView instanceof View) {
23 | View view = (View) findView;
24 | ViewParent parent = view.getParent();
25 | while (parent != null) {
26 | if (parent == viewParent) {
27 | result = true;
28 | break;
29 | }
30 |
31 | parent = parent.getParent();
32 | }
33 | }
34 | return result;
35 | }
36 | public static Field getgetObjectField(Object obj, String fieldName){
37 | java.lang.reflect.Field field = null;
38 | try {
39 |
40 | Class parentClass = obj.getClass();
41 | while (field == null) {
42 | try {
43 | field = parentClass.getDeclaredField(fieldName);
44 | } catch (Throwable e) {
45 | e.printStackTrace();
46 | }
47 |
48 | try {
49 | parentClass = parentClass.getSuperclass();
50 | if (parentClass == null) {
51 | break;
52 | }
53 | } catch (Throwable e) {
54 | e.printStackTrace();
55 | }
56 |
57 | }
58 |
59 | if (field != null && !field.isAccessible()) {
60 | field.setAccessible(true);
61 | }
62 | } catch (Throwable e) {
63 | e.printStackTrace();
64 | }
65 |
66 | return field;
67 | }
68 | public static Object getObjectFieldValue(Object obj, String fieldName) {
69 | Object result = null;
70 | try {
71 | java.lang.reflect.Field field = getgetObjectField(obj, fieldName);
72 | if (field != null) {
73 | field.setAccessible(true);
74 | result = field.get(obj);
75 | }
76 | } catch (Throwable e) {
77 | e.printStackTrace();
78 | }
79 |
80 | return result;
81 | }
82 | public static boolean setObjectField(Object obj, String fieldName, Object newValue) {
83 | boolean result = false;
84 | try {
85 | Field field = getgetObjectField(obj,fieldName);
86 | field.setAccessible(true);
87 | field.set(obj, newValue);
88 | result = true;
89 | } catch (Throwable e) {
90 | e.printStackTrace();
91 | }
92 |
93 | return result;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/ui/ListViewWithViewPager.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.ui;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 | import android.widget.ListView;
8 |
9 | public class ListViewWithViewPager extends ListView {
10 |
11 | private static final String TAG = "ListViewWithViewPager";
12 | private static final int DISTANCE_X_SCROLL = 10;
13 |
14 | private View mHeaderView = null;
15 | private float mHeaderWidth = 0;
16 | private float mHeaderHeight = 0;
17 |
18 | public ListViewWithViewPager(Context context) {
19 | super(context);
20 | }
21 |
22 | public ListViewWithViewPager(Context context, AttributeSet attrs, int defStyle) {
23 | super(context, attrs, defStyle);
24 |
25 | }
26 |
27 | public ListViewWithViewPager(Context context, AttributeSet attrs) {
28 | super(context, attrs);
29 | }
30 |
31 | /**
32 | * touch事件分发
33 | *
34 | * 在该方法中,将对触控到非HeaderView的事件进行拦截
35 | */
36 | @Override
37 | public boolean onInterceptTouchEvent(MotionEvent ev) {
38 |
39 | // boolean result;
40 | if (ev != null) {
41 |
42 | int action = ev.getAction();
43 | // MLog.d(TAG, "onInterceptTouchEvent action:"+action);
44 |
45 | if (MotionEvent.ACTION_DOWN == action) {
46 |
47 | if (mHeaderView != null) {
48 |
49 | mHeaderWidth = mHeaderView.getWidth();
50 | mHeaderHeight = mHeaderView.getHeight();
51 |
52 | View firstVisibleView = this.getChildAt(getFirstVisiblePosition());
53 | final float firstVisibleViewLeftY;
54 | if (firstVisibleView != null && firstVisibleView == mHeaderView) {
55 |
56 | if (Math.abs(firstVisibleView.getTop()) < mHeaderHeight) {
57 |
58 | firstVisibleViewLeftY = mHeaderHeight - (Math.abs(firstVisibleView.getTop()));
59 |
60 | // MLog.d(TAG,
61 | // "mHeaderWidth :"+mHeaderWidth+" mHeaderHeight:"+mHeaderHeight);
62 | if (mHeaderHeight != 0 && mHeaderWidth != 0) {
63 | // final float downX = ev.getX();
64 | final float downY = ev.getY();
65 | // MLog.d(TAG, "ev X:"+downX+" y:"+downY);
66 | // MLog.d(TAG,
67 | // "firstVisibleViewLeftY:"+firstVisibleViewLeftY);
68 |
69 | // 触控的区域为HeaderView区域,则不拦截事件
70 | if (firstVisibleViewLeftY > downY) {
71 |
72 | // MLog.d(TAG, "ListView不截获Touch事件");
73 |
74 | return false;
75 | }
76 |
77 | }
78 | }
79 | }
80 |
81 | }
82 | }
83 | }
84 |
85 | // MLog.d(TAG, "ListView截获Touch事件");
86 | if (ev != null) {
87 | return super.onInterceptTouchEvent(ev);
88 | }
89 | return false;
90 | }
91 |
92 | @Override
93 | public void addHeaderView(View v, Object data, boolean isSelectable) {
94 | super.addHeaderView(v, data, isSelectable);
95 | handlerView(v);
96 | }
97 |
98 | @Override
99 | public void addHeaderView(View v) {
100 | super.addHeaderView(v);
101 | handlerView(v);
102 | }
103 |
104 | private void handlerView(View v) {
105 | mHeaderView = v;
106 | }
107 |
108 | public View getHandlerHeaderView() {
109 | return mHeaderView;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/activity/HomePageActivity.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.KeyEvent;
6 |
7 |
8 | import com.android.androidtech.R;
9 | import com.android.androidtech.activity.base.BaseFragmentActivity;
10 | import com.android.androidtech.activity.base.StackLayout;
11 | import com.android.androidtech.fragment.base.BaseFragment;
12 | import com.android.androidtech.fragment.homepage.HomePageFragment;
13 | import com.android.androidtech.utils.GLog;
14 |
15 | /**
16 | * Created by yuchengluo on 2015/6/26.
17 | */
18 | public class HomePageActivity extends BaseFragmentActivity {
19 |
20 | private final static String TAG = "MusicMainWithMiniBarActivity";
21 | private int mFocusedTextColor, mTextColor;
22 | private StackLayout mMainFragmentContainer;
23 | private static final String MAIN_FRAGMENT_CONTENT = "main_content";
24 | public static final int CONTAINER_ID = R.id.homepage_fragment_detail;
25 | private int mViewIndex = TAB_VIEW_00;
26 |
27 |
28 | @Override
29 | public void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_homepage);
32 | mMainFragmentContainer = (StackLayout) findViewById(R.id.homepage_fragment_detail);
33 | makeNewContentFragmentStackManager(CONTAINER_ID, MAIN_FRAGMENT_CONTENT, mMainFragmentContainer);
34 | Bundle data = new Bundle();
35 | data.putInt(APP_INDEX_KEY, mViewIndex);
36 | addSecondFragment(HomePageFragment.class, data, null);
37 | }
38 |
39 | @Override
40 | protected void onNewIntent(Intent intent) {
41 | super.onNewIntent(intent);
42 | setIntent(intent);
43 | }
44 |
45 | @Override
46 | public boolean onKeyDown(int keyCode, KeyEvent event) {
47 | switch (keyCode) {
48 | case KeyEvent.KEYCODE_BACK:
49 | BaseFragment top = top();
50 | if (top != null && top.onKeyDown(keyCode, event)) {
51 | return true;
52 | }
53 | if (size() > 1) {
54 | popBackStack();
55 | return true;
56 | }
57 | break;
58 | case KeyEvent.KEYCODE_MENU:
59 | return true;
60 | }
61 |
62 | return super.onKeyDown(keyCode, event);
63 | }
64 |
65 | private static final int MSG_REFRESH_MUSIC_CIRCLE = 10000;
66 |
67 | @Override
68 | public void onStart() {
69 | super.onStart();
70 | }
71 |
72 | @Override
73 | protected void onResume() {
74 | super.onResume();
75 | GLog.d(TAG, "On Resume" + getClass().getSimpleName());
76 | }
77 |
78 | @Override
79 | protected void onPause() {
80 | super.onPause();
81 | GLog.d(TAG, "onPause " + getClass().getSimpleName());
82 | }
83 |
84 | @Override
85 | protected void onDestroy() {
86 | super.onDestroy();
87 | }
88 |
89 | @Override
90 | public void onStop() {
91 | super.onStop();
92 | }
93 |
94 | @Override
95 | public void finish() {
96 | super.finish();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/fragment/performance/ui/UiPerfFragment.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.fragment.performance.ui;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.view.animation.Animation;
10 | import android.widget.Button;
11 |
12 | import com.android.androidtech.R;
13 | import com.android.androidtech.activity.HomePageActivity;
14 | import com.android.androidtech.activity.ex.LayoutPerActivity;
15 | import com.android.androidtech.fragment.base.BaseFragment;
16 |
17 | /**
18 | * Created by yuchengluo on 2015/7/16.
19 | * UI Home page Fragment
20 | */
21 | public class UiPerfFragment extends BaseFragment implements View.OnClickListener {
22 | private Button mBtn_OverDraw,mBtn_Xml,mBtn_ListView,mBtn_Merge;
23 | private Context mContext = null;
24 | @Override
25 | protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
26 | mContext = getHostActivity();
27 | View view = inflater.inflate(R.layout.fm_ui_perf, container, false);
28 | mBtn_OverDraw = (Button)view.findViewById(R.id.btn_overdraw);
29 | mBtn_OverDraw.setOnClickListener(this);
30 | mBtn_Xml = (Button)view.findViewById(R.id.btn_xml);
31 | mBtn_Xml.setOnClickListener(this);
32 | mBtn_ListView = (Button)view.findViewById(R.id.btn_listview);
33 | mBtn_ListView.setOnClickListener(this);
34 | mBtn_Merge = (Button)view.findViewById(R.id.btn_merge_layout);
35 | mBtn_Merge.setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View v) {
38 | Intent it = new Intent(getHostActivity(), LayoutPerActivity.class);
39 | ((HomePageActivity) mContext).startActivity(it);
40 | }
41 | });
42 | return view;
43 | }
44 |
45 | @Override
46 | protected void resume() {
47 |
48 | }
49 |
50 | @Override
51 | protected void stop() {
52 |
53 | }
54 |
55 | @Override
56 | protected void pause() {
57 |
58 | }
59 |
60 | @Override
61 | protected void start() {
62 |
63 | }
64 |
65 | @Override
66 | public void onEnterAnimationEnd(Animation animation) {
67 |
68 | }
69 |
70 | @Override
71 | public void clearView() {
72 |
73 | }
74 |
75 | @Override
76 | public void clear() {
77 |
78 | }
79 |
80 | @Override
81 | protected void initData(Bundle data) {
82 |
83 | }
84 |
85 | @Override
86 | public void onClick(View v) {
87 | if(v.getId() == mBtn_OverDraw.getId()){
88 | Bundle mBundle = new Bundle();
89 | ((HomePageActivity) mContext).addSecondFragment(OverDrawFragment.class, mBundle, null);
90 | }else if(v.getId() == mBtn_Xml.getId()){
91 | Bundle mBundle = new Bundle();
92 | ((HomePageActivity) mContext).addSecondFragment(ViewStubDemoFragment.class, mBundle, null);
93 | }else if(v.getId() == mBtn_ListView.getId()){
94 | Bundle mBundle = new Bundle();
95 | ((HomePageActivity) mContext).addSecondFragment(ListViewFragment.class, mBundle, null);
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/monitor/ui/UiPerfMonitor.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.monitor.ui;
2 |
3 | import android.os.Looper;
4 |
5 | import com.android.androidtech.monitor.ui.sampling.CpuInfo;
6 | import com.android.androidtech.monitor.ui.sampling.CpuInfoSampler;
7 | import com.android.androidtech.utils.GLog;
8 |
9 | import java.io.File;
10 |
11 | /**
12 | * Created by yuchengluo on 2016/3/31.
13 | * UI Performance Monitor Manager
14 | */
15 | public class UiPerfMonitor implements UiPerfMonitorConfig, LogPrinterListener {
16 | private static UiPerfMonitor mInstance = null;
17 | private final String TAG = "UiPerfMonitor";
18 | private LogPrinter mLogPrinter;
19 | private LogWriteThread mLogWriteThread;
20 | private int monitorState = UI_PERF_MONITER_STOP;
21 | private CpuInfoSampler mCpuInfoSampler = null;
22 |
23 | public synchronized static UiPerfMonitor getmInstance() {
24 | if (null == mInstance) {
25 | mInstance = new UiPerfMonitor();
26 | }
27 | return mInstance;
28 | }
29 |
30 | //
31 | public UiPerfMonitor() {
32 | mCpuInfoSampler = new CpuInfoSampler();
33 | mLogPrinter = new LogPrinter(this);
34 | mLogWriteThread = new LogWriteThread();
35 | initLogpath();
36 | }
37 |
38 | public void startMonitor() {
39 | Looper.getMainLooper().setMessageLogging(mLogPrinter);
40 | monitorState = UI_PERF_MONITER_START;
41 | }
42 |
43 | public void stopMonitor() {
44 | Looper.getMainLooper().setMessageLogging(null);
45 | mCpuInfoSampler.stop();
46 | monitorState = UI_PERF_MONITER_STOP;
47 | }
48 |
49 | public boolean isMonitoring() {
50 | return monitorState == UI_PERF_MONITER_START;
51 | }
52 |
53 | //Init Log file dir
54 | private void initLogpath() {
55 | File logpath = new File(LOG_PATH);
56 | if (!logpath.exists()) {
57 | boolean mkdir = logpath.mkdir();
58 | GLog.d(TAG, "mkdir:" + mkdir + ":" + LOG_PATH);
59 | }
60 | }
61 |
62 |
63 | @Override
64 | public void onStartLoop() {
65 | mCpuInfoSampler.start();
66 | }
67 |
68 | @Override
69 | public void onEndLoop(long starttime, long endtime, String loginfo, @PER_LEVEL int level) {
70 | mCpuInfoSampler.stop();
71 | switch (level) {
72 | case UI_PERF_LEVEL_1:
73 | GLog.d(TAG, "onEndLoop TIME_WARNING_LEVEL_1 & cpusize:" + mCpuInfoSampler.getStatCpuInfoList().size());
74 | if (mCpuInfoSampler.getStatCpuInfoList().size() > 0) {
75 | StringBuffer sb = new StringBuffer("startTime:");
76 | sb.append(starttime);
77 | sb.append(" endTime:");
78 | sb.append(endtime);
79 | sb.append(" handleTime:");
80 | sb.append(endtime-starttime);
81 | for (CpuInfo info : mCpuInfoSampler.getStatCpuInfoList()) {
82 | sb.append("\r\n");
83 | sb.append(info.toString());
84 | }
85 | mLogWriteThread.saveLog(sb.toString());
86 | }
87 | break;
88 | case UI_PERF_LEVEL_2:
89 | break;
90 | default:
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/database/tables/BaseTable.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.database.tables;
2 |
3 | import android.content.ContentResolver;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.database.sqlite.SQLiteDatabase;
7 | import android.database.sqlite.SQLiteStatement;
8 |
9 | import com.android.androidtech.database.DBManager;
10 | import com.android.androidtech.utils.GLog;
11 |
12 |
13 | /**
14 | * 基于SqliteDataBase存储的数据抽象表
15 | * Created by yuchengluo on 2015/6/29.
16 | */
17 | public abstract class BaseTable {
18 | /**
19 | * 上下文指针
20 | */
21 | private Context mContext;
22 |
23 | /**
24 | * 构造函数
25 | *
26 | * @param context
27 | */
28 | public BaseTable(Context context) {
29 | mContext = context;
30 | }
31 |
32 | /**
33 | * 获取上下文指针
34 | *
35 | * @return
36 | */
37 | public Context getContext() {
38 | return mContext;
39 | }
40 |
41 | /**
42 | * 设置上下文指针
43 | *
44 | * @param context
45 | */
46 | public void setContext(Context context) {
47 | this.mContext = context;
48 |
49 | }
50 |
51 | /**
52 | * 获取ContentResolver
53 | *
54 | * @return
55 | */
56 | public ContentResolver getContentResolver() {
57 | return (mContext == null) ? null : mContext.getContentResolver();
58 | }
59 |
60 | /**
61 | * 获取表所属数据库
62 | *
63 | * @return
64 | */
65 | public SQLiteDatabase getSqliteDB() {
66 | return DBManager.getWriteDB(mContext.getApplicationContext());
67 | }
68 |
69 | /**
70 | * 获取表读数据库
71 | *
72 | * @return
73 | */
74 | public SQLiteDatabase getSqliteReadDB() {
75 | return DBManager.getReadDB(mContext.getApplicationContext());
76 | }
77 | /**
78 | * 获取SQL STATEMENT
79 | * */
80 | public abstract SQLiteStatement getSQLiteStatement();
81 | /**
82 | * 获取表名
83 | *
84 | * @return
85 | */
86 | public abstract String getTableName();
87 | /*
88 | * 获取所有键名
89 | * */
90 | public abstract String[] getAllKey();
91 | /**
92 | * @author kenzhang 查询表中元素数量,比原有的cursor.getCount()更高效
93 | * @return
94 | */
95 | public int getTotalCount() {
96 | Cursor cursor = null;
97 | try {
98 | SQLiteDatabase sqliteDb = getSqliteDB();
99 | if (sqliteDb != null) {
100 | cursor = sqliteDb.rawQuery("select count(*) from " + getTableName(), null);
101 | if (cursor != null && cursor.moveToFirst()) {
102 | int i = cursor.getInt(0);
103 | return i;
104 | }
105 | }
106 | } catch (Exception e) {
107 | GLog.e("BaseTable", e);
108 | } finally {
109 | if (cursor != null) {
110 | cursor.close();
111 | }
112 | }
113 | return -1;
114 | }
115 |
116 | protected static String kv(String key, String value) {
117 | return key + "=" + value;
118 | }
119 |
120 | protected static String kv(String key, long value) {
121 | return key + "=" + value;
122 | }
123 |
124 | protected static String kv(String key, int value) {
125 | return key + "=" + value;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/fragment/PerformanceFragment.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.fragment;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.view.animation.Animation;
9 | import android.widget.Button;
10 |
11 | import com.android.androidtech.R;
12 | import com.android.androidtech.activity.HomePageActivity;
13 | import com.android.androidtech.fragment.base.BaseFragment;
14 | import com.android.androidtech.fragment.performance.memory.BitmapMemeryFragment;
15 | import com.android.androidtech.fragment.performance.memory.ImageGridFragment;
16 | import com.android.androidtech.fragment.performance.ui.UiPerfFragment;
17 |
18 | /**
19 | * Created by yuchengluo on 2015/7/16.
20 | */
21 | public class PerformanceFragment extends BaseFragment implements View.OnClickListener {
22 |
23 | private Button mBtn_UiPerf,mBtn_MenPerf ,mBtn_BitMap,mBtn_Contact= null;
24 | private Context mContext = null;
25 | @Override
26 | protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
27 | mContext = getHostActivity();
28 | View view = inflater.inflate(R.layout.fm_performance, container, false);
29 | mBtn_UiPerf = (Button)view.findViewById(R.id.btn_ui_perf);
30 | mBtn_UiPerf.setOnClickListener(this);
31 |
32 | mBtn_MenPerf = (Button)view.findViewById(R.id.btn_men_perf);
33 | mBtn_MenPerf.setOnClickListener(this);
34 |
35 | mBtn_BitMap = (Button)view.findViewById(R.id.btn_bitmap_men);
36 | mBtn_BitMap.setOnClickListener(this);
37 |
38 | mBtn_Contact = (Button)view.findViewById(R.id.btn_contact);
39 | mBtn_Contact.setOnClickListener(this);
40 | return view;
41 | }
42 |
43 | @Override
44 | protected void resume() {
45 |
46 | }
47 |
48 | @Override
49 | protected void stop() {
50 |
51 | }
52 |
53 | @Override
54 | protected void pause() {
55 |
56 | }
57 |
58 | @Override
59 | protected void start() {
60 |
61 | }
62 |
63 | @Override
64 | public void onEnterAnimationEnd(Animation animation) {
65 |
66 | }
67 |
68 | @Override
69 | public void clearView() {
70 |
71 | }
72 |
73 | @Override
74 | public void clear() {
75 |
76 | }
77 |
78 | @Override
79 | protected void initData(Bundle data) {
80 |
81 | }
82 |
83 | @Override
84 | public void onClick(View v) {
85 | if(v.getId() == mBtn_UiPerf.getId()){
86 | Bundle mBundle = new Bundle();
87 | ((HomePageActivity) mContext).addSecondFragment(UiPerfFragment.class, mBundle, null);
88 | }else if(v.getId() == mBtn_MenPerf.getId()){
89 | Bundle mBundle = new Bundle();
90 | ((HomePageActivity) mContext).addSecondFragment(ImageGridFragment.class, mBundle, null);
91 | }else if(v.getId() == mBtn_BitMap.getId()){
92 | Bundle mBundle = new Bundle();
93 | ((HomePageActivity) mContext).addSecondFragment(BitmapMemeryFragment.class, mBundle, null);
94 | }else if(v.getId() == mBtn_Contact.getId()){
95 | Bundle mBundle = new Bundle();
96 | ((HomePageActivity) mContext).addSecondFragment(ContactFragment.class, mBundle, null);
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/ui/MultiCardsView.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.ui;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Rect;
6 | import android.graphics.Region;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 |
10 | import com.android.androidtech.fragment.performance.ui.SingleCard;
11 | import com.android.androidtech.utils.GLog;
12 |
13 | import java.util.ArrayList;
14 |
15 | /**
16 | * Created by yuchengluo on 2015/7/16.
17 | */
18 | public class MultiCardsView extends View{
19 | private ArrayList cardsList = new ArrayList(5);
20 | private boolean enableOverdrawOpt = true;
21 |
22 | public MultiCardsView(Context context) {
23 | this(context, null, 0);
24 | }
25 | public MultiCardsView(Context context, AttributeSet attrs) {
26 | this(context, attrs, 0);
27 | }
28 | public MultiCardsView(Context context, AttributeSet attrs, int defStyleAttr) {
29 | super(context, attrs, defStyleAttr);
30 | }
31 |
32 | public void addCards(SingleCard card) {
33 | cardsList.add(card);
34 | }
35 | //设置是否消除过度绘制
36 | public void enableOverdrawOpt(boolean enableOrNot) {
37 | this.enableOverdrawOpt = enableOrNot;
38 | invalidate();
39 | }
40 | @Override
41 | public void onDraw(Canvas canvas) {
42 | super.onDraw(canvas);
43 | if (cardsList == null || canvas == null)
44 | return;
45 | Rect clip = canvas.getClipBounds();
46 | GLog.d("draw", String.format("clip bounds %d %d %d %d", clip.left, clip.top, clip.right, clip.bottom));
47 | //根据enableOverdrawOpt值来调用不同的绘制方法,对比效果
48 | if (enableOverdrawOpt) {
49 | drawCardsWithotOverDraw(canvas, cardsList.size() - 1);
50 | } else {
51 | drawCardsNormal(canvas, cardsList.size() - 1);
52 | }
53 | }
54 | //没有过度绘制的实现
55 | protected void drawCardsWithotOverDraw(Canvas canvas, int index) {
56 | if (canvas == null || index < 0 || index >= cardsList.size())
57 | return;
58 | SingleCard card = cardsList.get(index);
59 | //判断是否没和某个卡片相交,从而跳过那些非矩形区域内的绘制操作
60 | if (card != null && !canvas.quickReject(card.area, Canvas.EdgeType.BW)) {
61 | int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
62 | //只绘制可见区域
63 | if (canvas.clipRect(card.area, Region.Op.DIFFERENCE)) {
64 | drawCardsWithotOverDraw(canvas, index - 1);
65 | }
66 | canvas.restoreToCount(saveCount);
67 | saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
68 | //只绘制可见区域
69 | if (canvas.clipRect(card.area)) {
70 | GLog.d("draw", "overdraw opt: draw cards index: " + index);
71 | Rect clip = canvas.getClipBounds();
72 | GLog.d("draw", String.format("current clip bounds %d %d %d %d", clip.left, clip.top, clip.right, clip.bottom));
73 | card.draw(canvas);
74 | }
75 | canvas.restoreToCount(saveCount);
76 | }else{
77 | drawCardsWithotOverDraw(canvas, index - 1);
78 | }
79 | }
80 | //普通绘制
81 | protected void drawCardsNormal(Canvas canvas, int index) {
82 | if (canvas == null || index < 0 || index >= cardsList.size())
83 | return;
84 | SingleCard card = cardsList.get(index);
85 | if (card != null) {
86 | drawCardsNormal(canvas, index - 1);
87 | GLog.d("draw", "draw cards index: " + index);
88 | card.draw(canvas);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/CrashHandler.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 | import android.os.Build;
7 | import android.os.Environment;
8 |
9 | import com.android.androidtech.utils.GLog;
10 |
11 | import java.io.BufferedWriter;
12 | import java.io.File;
13 | import java.io.FileWriter;
14 | import java.io.IOException;
15 | import java.io.PrintWriter;
16 | import java.text.SimpleDateFormat;
17 | import java.util.Date;
18 |
19 | import android.os.Process;
20 |
21 | /**
22 | * Created by yuchengluo on 2016/6/16.
23 | */
24 | public class CrashHandler implements Thread.UncaughtExceptionHandler {
25 | private static final String TAG = "CrashHandler";
26 | private static final String CRASH_FILE_NAME = "crash";
27 | private static final String CRASH_FILE_PATH = Environment.getExternalStorageDirectory().getPath() + "/log/";
28 | //log文件的后缀名
29 | private static final String CRASH_FILE_NAME_SUFFIX = ".txt";
30 |
31 |
32 | //系统默认的异常处理(默认情况下,系统会终止当前的异常程序)
33 | private Thread.UncaughtExceptionHandler mDefaultCrashHandler;
34 |
35 | private Context mContext;
36 |
37 | //这里主要完成初始化工作
38 | public void init(Context context) {
39 | //获取系统默认的异常处理器
40 | mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
41 | //将当前实例设为系统默认的异常处理器
42 | Thread.setDefaultUncaughtExceptionHandler(this);
43 | //获取Context,方便内部使用
44 | mContext = context;
45 | //可以在初始化后在异步线程中上报上次保存的Crash信息
46 | }
47 |
48 | /**
49 | * 这个是最关键的方法,当程序中有未被捕获的异常,系统将会自动调用#uncaughtException方法
50 | * thread为出现未捕获异常的线程,ex为未捕获的异常,有了这个ex,我们就可以得到异常信息。
51 | */
52 | @Override
53 | public void uncaughtException(Thread thread, Throwable ex) {
54 | try {
55 | //导出异常信息到SD卡中
56 | dumpExceptionToSDCard(ex);
57 | //这里可以通过网络上传异常信息到服务器,便于开发人员分析日志从而解决bug
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | }
61 |
62 | //打印出当前调用栈信息
63 | ex.printStackTrace();
64 |
65 | //如果系统提供了默认的异常处理器,则交给系统去结束我们的程序,否则就由我们自己结束自己
66 | if (mDefaultCrashHandler != null) {
67 | mDefaultCrashHandler.uncaughtException(thread, ex);
68 | } else {
69 | Process.killProcess(Process.myPid());
70 | }
71 |
72 | }
73 |
74 | private void dumpExceptionToSDCard(Throwable ex) throws IOException {
75 | //如果SD卡不存在或无法使用,则无法把异常信息写入SD卡
76 | if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
77 | GLog.e(TAG, "sdcard unmounted,skip dump exception");
78 | return;
79 | }
80 | File dir = new File(CRASH_FILE_PATH);
81 | if (!dir.exists()) {
82 | dir.mkdirs();
83 | }
84 | long current = System.currentTimeMillis();
85 | String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
86 | //以当前时间创建log文件
87 | File file = new File(CRASH_FILE_PATH + CRASH_FILE_NAME + time + CRASH_FILE_NAME_SUFFIX);
88 |
89 | try {
90 | PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
91 | //导出发生异常的时间
92 | pw.println(time);
93 | //获取手机信息
94 | getPhoneInfo(pw);
95 |
96 | pw.println();
97 | //导出异常的调用栈信息
98 | ex.printStackTrace(pw);
99 |
100 | pw.close();
101 | } catch (Exception e) {
102 | GLog.e(TAG, "dump crash info failed");
103 | }
104 | }
105 |
106 | private void getPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException {
107 | //TODO 上报一些辅助信息,如应用版本号,系统版本号,手机型号等,方便数据分析和归类
108 | }
109 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/utils/dex/ZipUtil.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.utils.dex;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.RandomAccessFile;
6 | import java.util.zip.CRC32;
7 | import java.util.zip.ZipException;
8 |
9 | /**
10 | * Created by yuchengluo on 2015/10/30.
11 | */
12 | public class ZipUtil {
13 |
14 | static class CentralDirectory {
15 | long offset;
16 | long size;
17 | }
18 |
19 | /* redefine those constant here because of bug 13721174 preventing to compile using the
20 | * constants defined in ZipFile */
21 | private static final int ENDHDR = 22;
22 | private static final int ENDSIG = 0x6054b50;
23 |
24 | /**
25 | * Size of reading buffers.
26 | */
27 | private static final int BUFFER_SIZE = 0x4000;
28 |
29 | /**
30 | * Compute crc32 of the central directory of an apk. The central directory contains
31 | * the crc32 of each entries in the zip so the computed result is considered valid for the whole
32 | * zip file. Does not support zip64 nor multidisk but it should be OK for now since ZipFile does
33 | * not either.
34 | */
35 | static long getZipCrc(File apk) throws IOException {
36 | RandomAccessFile raf = new RandomAccessFile(apk, "r");
37 | try {
38 | CentralDirectory dir = findCentralDirectory(raf);
39 |
40 | return computeCrcOfCentralDir(raf, dir);
41 | } finally {
42 | raf.close();
43 | }
44 | }
45 |
46 | /* Package visible for testing */
47 | static CentralDirectory findCentralDirectory(RandomAccessFile raf) throws IOException,
48 | ZipException {
49 | long scanOffset = raf.length() - ENDHDR;
50 | if (scanOffset < 0) {
51 | throw new ZipException("File too short to be a zip file: " + raf.length());
52 | }
53 |
54 | long stopOffset = scanOffset - 0x10000 /* ".ZIP file comment"'s max length */;
55 | if (stopOffset < 0) {
56 | stopOffset = 0;
57 | }
58 |
59 | int endSig = Integer.reverseBytes(ENDSIG);
60 | while (true) {
61 | raf.seek(scanOffset);
62 | if (raf.readInt() == endSig) {
63 | break;
64 | }
65 |
66 | scanOffset--;
67 | if (scanOffset < stopOffset) {
68 | throw new ZipException("End Of Central Directory signature not found");
69 | }
70 | }
71 | // Read the End Of Central Directory. ENDHDR includes the signature
72 | // bytes,
73 | // which we've already read.
74 |
75 | // Pull out the information we need.
76 | raf.skipBytes(2); // diskNumber
77 | raf.skipBytes(2); // diskWithCentralDir
78 | raf.skipBytes(2); // numEntries
79 | raf.skipBytes(2); // totalNumEntries
80 | CentralDirectory dir = new CentralDirectory();
81 | dir.size = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;
82 | dir.offset = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;
83 | return dir;
84 | }
85 |
86 | /* Package visible for testing */
87 | static long computeCrcOfCentralDir(RandomAccessFile raf, CentralDirectory dir)
88 | throws IOException {
89 | CRC32 crc = new CRC32();
90 | long stillToRead = dir.size;
91 | raf.seek(dir.offset);
92 | int length = (int) Math.min(BUFFER_SIZE, stillToRead);
93 | byte[] buffer = new byte[BUFFER_SIZE];
94 | length = raf.read(buffer, 0, length);
95 | while (length != -1) {
96 | crc.update(buffer, 0, length);
97 | stillToRead -= length;
98 | if (stillToRead == 0) {
99 | break;
100 | }
101 | length = (int) Math.min(BUFFER_SIZE, stillToRead);
102 | length = raf.read(buffer, 0, length);
103 | }
104 | return crc.getValue();
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/utils/CpuFreqSet.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.utils;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.DataOutputStream;
5 | import java.io.IOException;
6 | import java.util.ArrayList;
7 |
8 | /**
9 | * Created by yuchengluo on 2016/7/5.
10 | */
11 |
12 | public class CpuFreqSet {
13 | public class CPUFreqSetting {
14 | /**
15 | * cpu cat命令大全
16 | * cat [%cpuFreqPath%]/cpuinfo_cur_freq (当前cpu频率)
17 | * cat [%cpuFreqPath%]/cpuinfo_max_freq (最大cpu频率)
18 | * cat [%cpuFreqPath%]/cpuinfo_min_freq (最小cpu频率)
19 | * cat [%cpuFreqPath%]/related_cpus (cpu数量标号,从0开始,如果是双核,结果为0,1)
20 | * cat [%cpuFreqPath%]/scaling_available_frequencies (cpu所有可用频率)
21 | * cat [%cpuFreqPath%]/scaling_available_governors (cpu所有可用调控模式)
22 | * cat [%cpuFreqPath%]/scaling_available_governors (cpu所有可用调控模式)
23 | * cat [%cpuFreqPath%]/scaling_cur_freq (?????)
24 | * cat [%cpuFreqPath%]/scaling_driver (?????)
25 | * cat [%cpuFreqPath%]/scaling_governor (?????)
26 | * cat [%cpuFreqPath%]/scaling_max_freq (?????)
27 | * cat [%cpuFreqPath%]/scaling_min_freq (?????)
28 | * cat [%cpuFreqPath%]/scaling_setspeed (?????)
29 | * cat [%cpuFreqPath%]/cpuinfo_transition_latency (?????)
30 | */
31 | private final String TAG = "CpuFreqSet";
32 | private final String cpuFreqPath = "/sys/devices/system/cpu/cpu0/cpufreq";
33 | // private final static String PERFORMANCE_GOVERNOR = "performance";
34 | // private final static String POWER_SAVE_GOVERNOR = "performance";
35 | // private final static String ONDEMAND_GOVERNOR = "performance";
36 | // private final static String CONSERVATIVE_GOVERNOR = "performance";
37 | // private final static String USERSAPCE_GOVERNOR = "performance";
38 | /**
39 | * 获取当前CPU调控模式
40 | */
41 | public void getCpuCurGovernor() {
42 | try {
43 | DataInputStream is = null;
44 | Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_governor");
45 | is = new DataInputStream(process.getInputStream());
46 | String line = is.readLine();
47 | } catch (IOException e) {
48 | e.printStackTrace();
49 | }
50 | }
51 |
52 | /**
53 | * 设置CPU调控模式
54 | */
55 | private boolean writeCpuGovernor(String governor) {
56 | DataOutputStream os = null;
57 | byte[] buffer = new byte[256];
58 | String command = "echo " + governor + " > " + cpuFreqPath + "/scaling_governor";
59 | try {
60 | Process process = Runtime.getRuntime().exec("su");
61 | os = new DataOutputStream(process.getOutputStream());
62 | os.writeBytes(command + "\n");
63 | os.writeBytes("exit\n");
64 | os.flush();
65 | process.waitFor();
66 | } catch (IOException e) {
67 | return false;
68 | } catch (InterruptedException e) {
69 | e.printStackTrace();
70 | }
71 | return true;
72 | }
73 |
74 | /**
75 | * 获得CPU所有调控模式
76 | * @return
77 | */
78 | private ArrayList readCpuGovernors() {
79 | ArrayList governors = new ArrayList();
80 | DataInputStream is = null;
81 | try {
82 | Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_available_governors");
83 | is = new DataInputStream(process.getInputStream());
84 | String line = is.readLine();
85 |
86 | String[] strs = line.split(" ");
87 | for (int i = 0; i < strs.length; i++)
88 | governors.add(strs[i]);
89 | } catch (IOException e) {
90 | }
91 | return governors;
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/utils/dex/ReflectUtil.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.utils.dex;
2 |
3 | import java.lang.reflect.Field;
4 | import java.lang.reflect.Method;
5 | import java.util.Arrays;
6 |
7 | /**
8 | * Created by yuchengluo on 2015/10/30.
9 | */
10 | public class ReflectUtil {
11 |
12 | public static boolean setObjectField(Object obj, String fieldName, Object newValue) {
13 | boolean result = false;
14 | try {
15 | Field field = obj.getClass().getDeclaredField(fieldName);
16 | field.setAccessible(true);
17 | field.set(obj, newValue);
18 | result = true;
19 | } catch (Throwable e) {
20 | // e.printStackTrace();
21 | }
22 |
23 | return result;
24 | }
25 |
26 | public static Method getObjectMethod(Object obj, String methodName) {
27 | try {
28 | Method[] methods = obj.getClass().getDeclaredMethods();
29 | if (methods != null) {
30 | for (Method method : methods) {
31 | if (method != null && method.getName().equals(methodName)) {
32 | return method;
33 | }
34 | }
35 | }
36 | } catch (Throwable e) {
37 | }
38 |
39 | return null;
40 | }
41 |
42 | public static Method getObjectMethodByArgs(Object instance, String name, Class... parameterTypes)
43 | throws NoSuchMethodException {
44 | Class clazz = instance.getClass();
45 |
46 | while (clazz != null) {
47 | try {
48 | Method method = clazz.getDeclaredMethod(name, parameterTypes);
49 | if (!method.isAccessible()) {
50 | method.setAccessible(true);
51 | }
52 |
53 | return method;
54 | } catch (NoSuchMethodException var5) {
55 | clazz = clazz.getSuperclass();
56 | }
57 | }
58 | throw new NoSuchMethodException("Method " + name + " with parameters " + Arrays.asList(parameterTypes)
59 | + " not found in " + instance.getClass());
60 | }
61 |
62 | public static Field getObjectField(Object obj, String fieldName) {
63 | Field field = null;
64 | try {
65 |
66 | Class parentClass = obj.getClass();
67 | while (field == null) {
68 | try {
69 | field = parentClass.getDeclaredField(fieldName);
70 | } catch (Throwable e) {
71 | e.printStackTrace();
72 | }
73 |
74 | try {
75 | parentClass = parentClass.getSuperclass();
76 | if (parentClass == null) {
77 | break;
78 | }
79 | } catch (Throwable e) {
80 | e.printStackTrace();
81 | }
82 |
83 | }
84 |
85 | if (field != null && !field.isAccessible()) {
86 | field.setAccessible(true);
87 | }
88 | } catch (Throwable e) {
89 | e.printStackTrace();
90 | }
91 |
92 | return field;
93 | }
94 |
95 | public static Object getObjectFieldValue(Object obj, String fieldName) {
96 | Object result = null;
97 | try {
98 | Field field = getObjectField(obj, fieldName);
99 | if (field != null) {
100 | field.setAccessible(true);
101 | result = field.get(obj);
102 | }
103 | } catch (Throwable e) {
104 | e.printStackTrace();
105 | }
106 |
107 | return result;
108 | }
109 |
110 | public static Object invoke(Object obj, String methodName, Object[] args) {
111 | Object result = null;
112 | try {
113 | Method method = getObjectMethod(obj, methodName);
114 | if (method != null) {
115 | method.setAccessible(true);
116 | result = method.invoke(obj, args);
117 | }
118 | } catch (Throwable e) {
119 | e.printStackTrace();
120 | }
121 |
122 | return result;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/monitor/ui/LogWriteThread.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.monitor.ui;
2 |
3 | import android.os.Handler;
4 | import android.os.HandlerThread;
5 | import android.util.Log;
6 |
7 | import com.android.androidtech.utils.GLog;
8 |
9 | import java.io.BufferedWriter;
10 | import java.io.File;
11 | import java.io.FileOutputStream;
12 | import java.io.IOException;
13 | import java.io.OutputStreamWriter;
14 | import java.io.RandomAccessFile;
15 | import java.text.SimpleDateFormat;
16 |
17 | /**
18 | * Created by yuchengluo on 2015/4/5.
19 | * д��־�߳�
20 | */
21 | public class LogWriteThread implements UiPerfMonitorConfig{
22 | private Handler mWriteHandler = null;
23 | private final Object FILE_LOCK = new Object();
24 | private final SimpleDateFormat FILE_NAME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
25 | private final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
26 | private final String TAG = "LogWriteThread";
27 | public void saveLog(final String loginfo) {
28 | getmControlHandler().post(new Runnable() {
29 | @Override
30 | public void run() {
31 | synchronized (FILE_LOCK) {
32 | saveLog2Local(loginfo);
33 | }
34 | }
35 | });
36 | }
37 | private void saveLog2Local(String info){
38 | long time = System.currentTimeMillis();
39 | File logFile = new File(LOG_PATH + "/" + FILENAME + "-" + FILE_NAME_FORMATTER.format(time) + ".txt");
40 | StringBuffer mSb = new StringBuffer("/***************************************/\r\n");
41 | mSb.append(TIME_FORMATTER.format(time));
42 | mSb.append("\r\n/***************************************/\r\n");
43 | mSb.append(info+ "\r\n");
44 | GLog.d(TAG, "saveLogToSDCard: "+ mSb.toString());
45 | if(logFile.exists()){
46 | writeLog4SameFile(logFile.getPath(),mSb.toString());
47 | }else{
48 | BufferedWriter writer = null;
49 | try {
50 | OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(logFile.getPath(), true), "UTF-8");
51 | writer = new BufferedWriter(out);
52 | writer.write(mSb.toString());
53 | writer.flush();
54 | writer.close();
55 | writer = null;
56 | } catch (Throwable t) {
57 | Log.e(TAG, "saveLogToSDCard: ", t);
58 | } finally {
59 | try {
60 | if (writer != null) {
61 | writer.close();
62 | writer = null;
63 | }
64 | } catch (Exception e) {
65 | GLog.e(TAG, "saveLogToSDCard: ", e);
66 | }
67 | }
68 | }
69 | }
70 | /**
71 | *
72 | * @param fileName
73 | * @param content
74 | */
75 | public static void writeLog4SameFile(String fileName, String content) {
76 | RandomAccessFile randomFile = null;
77 | try {
78 | randomFile = new RandomAccessFile(fileName, "rw");
79 | long fileLength = randomFile.length();
80 | randomFile.seek(fileLength);
81 | randomFile.writeBytes(content);
82 | } catch (IOException e) {
83 | e.printStackTrace();
84 | }finally {
85 | if(randomFile != null){
86 | try {
87 | randomFile.close();
88 | } catch (IOException e) {
89 | e.printStackTrace();
90 | }
91 | }
92 | }
93 | }
94 | public void send2Server(){
95 | getmControlHandler().post(new Runnable() {
96 | @Override
97 | public void run() {
98 | //TODO send to server
99 | }
100 | });
101 | }
102 | private Handler getmControlHandler() {
103 | if (null == mWriteHandler) {
104 | HandlerThread mHT = new HandlerThread("SamplerThread");
105 | mHT.start();
106 | mWriteHandler = new Handler(mHT.getLooper());
107 | }
108 | return mWriteHandler;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/fragment/base/MyFragmentPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.fragment.base;
2 |
3 | import android.os.Parcelable;
4 | import android.os.SystemClock;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v4.app.FragmentManager;
7 | import android.support.v4.app.FragmentTransaction;
8 | import android.support.v4.view.PagerAdapter;
9 | import android.view.View;
10 |
11 | import com.android.androidtech.utils.GLog;
12 |
13 |
14 | public abstract class MyFragmentPagerAdapter extends PagerAdapter {
15 |
16 | private static final String TAG = "MyFragmentPagerAdapter";
17 | private static final boolean DEBUG = false;
18 | private String mTag;
19 |
20 | private final FragmentManager mFragmentManager;
21 | private FragmentTransaction mCurTransaction = null;
22 | private Fragment mCurrentPrimaryItem = null;
23 |
24 | public MyFragmentPagerAdapter(FragmentManager fm) {
25 | this(fm, "time is:" + SystemClock.currentThreadTimeMillis());
26 | }
27 |
28 | public MyFragmentPagerAdapter(FragmentManager fm, String Tag) {
29 | mFragmentManager = fm;
30 | mTag = Tag;
31 | }
32 |
33 | public abstract Fragment getItem(int position);
34 |
35 | @Override
36 | public void startUpdate(View container) {
37 | }
38 |
39 | @Override
40 | public Object instantiateItem(View container, int position) {
41 | if (mCurTransaction == null) {
42 | mCurTransaction = mFragmentManager.beginTransaction();
43 | }
44 |
45 | // Do we already have this fragment?
46 | String name = makeFragmentName(container.getId(), position);
47 | GLog.d(TAG, "instantiateItem name is:" + name);
48 | Fragment fragment = mFragmentManager.findFragmentByTag(name);
49 | GLog.d(TAG, "instantiateItem fragment is:" + fragment);
50 | if (fragment != null) {
51 | if (DEBUG)
52 | GLog.d(TAG, "Attaching item #" + position + ": f=" + fragment);
53 | mCurTransaction.attach(fragment);
54 | } else {
55 | fragment = getItem(position);
56 | if (fragment == null) {
57 | return null;
58 | }
59 | GLog.d(TAG, "instantiateItem getItem fragment is:" + fragment);
60 | if (DEBUG)
61 | GLog.d(TAG, "Adding item #" + position + ": f=" + fragment);
62 | mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), position));
63 | }
64 | if (fragment != mCurrentPrimaryItem) {
65 | fragment.setMenuVisibility(false);
66 | }
67 |
68 | return fragment;
69 | }
70 |
71 | @Override
72 | public void destroyItem(View container, int position, Object object) {
73 | if (mCurTransaction == null) {
74 | mCurTransaction = mFragmentManager.beginTransaction();
75 | }
76 | if (DEBUG)
77 | GLog.d(TAG, "Detaching item #" + position + ": f=" + object + " v=" + ((Fragment) object).getView());
78 | mCurTransaction.detach((Fragment) object);
79 | }
80 |
81 | @Override
82 | public void setPrimaryItem(View container, int position, Object object) {
83 | Fragment fragment = (Fragment) object;
84 | if (fragment != mCurrentPrimaryItem) {
85 | if (mCurrentPrimaryItem != null) {
86 | mCurrentPrimaryItem.setMenuVisibility(false);
87 | }
88 | if (fragment != null) {
89 | fragment.setMenuVisibility(true);
90 | }
91 | mCurrentPrimaryItem = fragment;
92 | }
93 | }
94 |
95 | @Override
96 | public void finishUpdate(View container) {
97 | if (mCurTransaction != null) {
98 | mCurTransaction.commitAllowingStateLoss();
99 | mCurTransaction = null;
100 | mFragmentManager.executePendingTransactions();
101 | }
102 | }
103 |
104 | @Override
105 | public boolean isViewFromObject(View view, Object object) {
106 | return ((Fragment) object).getView() == view;
107 | }
108 |
109 | @Override
110 | public Parcelable saveState() {
111 | return null;
112 | }
113 |
114 | @Override
115 | public void restoreState(Parcelable state, ClassLoader loader) {
116 | }
117 |
118 | private String makeFragmentName(int viewId, int index) {
119 | return "android:switcher:" + viewId + ":" + index + ":" + mTag;
120 | }
121 |
122 | public void clear() {
123 | if (mCurTransaction == null) {
124 | mCurTransaction = mFragmentManager.beginTransaction();
125 | }
126 | try {
127 | for (int i = 0; i < getCount(); i++) {
128 | Fragment f = (Fragment) getItem(i);
129 | mCurTransaction.remove(f);
130 | }
131 | mCurTransaction.commitAllowingStateLoss();
132 | } catch (Exception e) {
133 | e.printStackTrace();
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/fragment/ContactFragment.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.fragment;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.view.animation.Animation;
9 | import android.widget.BaseAdapter;
10 | import android.widget.ImageView;
11 | import android.widget.ListView;
12 | import android.widget.TextView;
13 |
14 | import com.android.androidtech.GmfSharedPreferences;
15 | import com.android.androidtech.R;
16 | import com.android.androidtech.business.contact.ContactInfo;
17 | import com.android.androidtech.business.contact.ContactsManager;
18 | import com.android.androidtech.fragment.base.BaseFragment;
19 |
20 | import java.util.ArrayList;
21 |
22 |
23 | /**
24 | * Created by yuchengluo on 2015/6/29.
25 | */
26 | public class ContactFragment extends BaseFragment {
27 | //private List> mData;
28 | private ArrayList mData;
29 | private ListView listView;
30 | private Context mContext;
31 | boolean bool = false;
32 | @Override
33 | protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
34 | mContext = getHostActivity();
35 | View view = inflater.inflate(R.layout.fm_listview, container, false);
36 |
37 | MyAdapter adapter = new MyAdapter(mContext);//创建一个适配器
38 |
39 | listView = (ListView) view.findViewById(R.id.listView);//实例化ListView
40 | if(!GmfSharedPreferences.getInstance().getSyncSysContactState()) {
41 | mData = ContactsManager.getInstance().getTestContactInfo();//为刚才的变量赋值
42 | }
43 | listView.setAdapter(adapter);//为ListView控件绑定适配器
44 | return view;
45 | }
46 |
47 | @Override
48 | protected void resume() {
49 |
50 | }
51 |
52 | @Override
53 | protected void stop() {
54 |
55 | }
56 |
57 | @Override
58 | protected void pause() {
59 |
60 | }
61 |
62 | @Override
63 | protected void start() {
64 |
65 | }
66 |
67 | @Override
68 | public void onEnterAnimationEnd(Animation animation) {
69 |
70 | }
71 |
72 | @Override
73 | public void clearView() {
74 |
75 | }
76 |
77 | @Override
78 | public void clear() {
79 |
80 | }
81 |
82 | @Override
83 | protected void initData(Bundle data) {
84 |
85 | }
86 |
87 | /**
88 | * 自定义适配器
89 | */
90 | public class MyAdapter extends BaseAdapter {
91 | private LayoutInflater mInflater;// 动态布局映射
92 |
93 | private class ItemHolder {
94 | TextView title;
95 | TextView time;
96 | TextView info;
97 | }
98 | public MyAdapter(Context context) {
99 | this.mInflater = LayoutInflater.from(context);
100 | }
101 |
102 | // 决定ListView有几行可见
103 | @Override
104 | public int getCount() {
105 | if(null == mData){
106 | return 0;
107 | }
108 | return mData.size();// ListView的条目数
109 | }
110 |
111 | @Override
112 | public Object getItem(int arg0) {
113 | return null;
114 | }
115 |
116 | @Override
117 | public long getItemId(int arg0) {
118 | return 0;
119 | }
120 |
121 | @Override
122 | public View getView(int position, View convertView, ViewGroup parent) {
123 | ItemHolder itemHolder = null;
124 | if(convertView == null) {
125 | convertView = mInflater.inflate(R.layout.item_listview_test, null);//根据布局文件实例化view
126 | itemHolder = new ItemHolder();
127 | itemHolder.title = (TextView) convertView.findViewById(R.id.title);//找某个控件
128 | itemHolder.time = (TextView) convertView.findViewById(R.id.time);//找某个控件
129 | itemHolder.info = (TextView) convertView.findViewById(R.id.info);
130 | convertView.setTag(itemHolder);
131 | }else{
132 | itemHolder = (ItemHolder)convertView.getTag();
133 | }
134 | itemHolder.info.setText(mData.get(position).getContactId()+ "");
135 | itemHolder.time.setText(mData.get(position).getContactNum() );//给该控件设置数据(数据从集合类中来)
136 | itemHolder.title.setText(mData.get(position).getContactName());//给该控件设置数据(数据从集合类中来)
137 | return convertView;
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/database/DBManager.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.database;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | import com.android.androidtech.database.tables.ContactInfoTable;
8 | import com.android.androidtech.database.tables.DBConfig;
9 | import com.android.androidtech.utils.GLog;
10 |
11 |
12 | /**
13 | * * Copyright (C) 1998-2014 TENCENT Inc.All Rights Reserved.
14 | *
15 | * @author yuchengluo
16 | * @Description: DB管理类,主要为创建表及DB升级
17 | * @date 2013-2-15 modify
18 | */
19 | public class DBManager implements DBConfig {
20 | private static final String TAG = "DBManager";
21 | private static SQLiteDatabase mDB = null;
22 | private static SQLiteDatabase mDBReadable = null;
23 | private static DatabaseHelper mDatabaseHelper = null;
24 |
25 | public static void close() {
26 | if (mDB != null) {
27 | try {
28 | mDB.close();
29 | } catch (Exception e) {
30 | }
31 | mDB = null;
32 | GLog.i(TAG, "[DBManager]close()");
33 | }
34 | if (mDBReadable != null) {
35 | try {
36 | mDBReadable.close();
37 | } catch (Exception e) {
38 | }
39 | mDBReadable = null;
40 | GLog.i(TAG, "[DBManager] mDBReadable close()");
41 | }
42 | }
43 |
44 | private static DatabaseHelper getDatabaseHelper(Context AppContex) {
45 | if (mDatabaseHelper == null) {
46 | mDatabaseHelper = new DatabaseHelper(AppContex);
47 | }
48 | return mDatabaseHelper;
49 | }
50 |
51 | /**
52 | * @param AppContext 这里的Context一定要用ApplicationContext 初始化DB
53 | * @return
54 | */
55 | public static synchronized void InitDB(Context AppContext) {
56 | // GLog.i(TAG, "getDB");
57 | // 暂时在启动初始化,如果初始化时间较长,在第一次使用初使化也是一种考虑方法
58 | getWriteDB(AppContext);
59 | getReadDB(AppContext);
60 | }
61 |
62 | /**
63 | * 获取写DB
64 | */
65 | public static synchronized SQLiteDatabase getWriteDB(Context AppContext) {
66 | // GLog.i(TAG, "getDB");
67 | if (mDB == null || !mDB.isOpen()) {
68 | mDB = getDatabaseHelper(AppContext).getWritableDatabase();
69 | // if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
70 | // // mDB.enableWriteAheaGLogging();
71 | // GLog.i(TAG, "[DBManager]getDB() enableWriteAheaGLogging");
72 | // }
73 | GLog.i(TAG, "[DBManager]getWriteDB()");
74 | }
75 | return mDB;
76 | }
77 |
78 | /**
79 | * 获取只读DBHelper
80 | */
81 | public static synchronized SQLiteDatabase getReadDB(Context AppContext) {
82 | // GLog.i(TAG, "getDB");
83 | if (mDBReadable == null || !mDBReadable.isOpen()) {
84 | mDBReadable = getDatabaseHelper(AppContext).getReadableDatabase();
85 |
86 | GLog.i(TAG, "[DBManager]getReadDB()");
87 | }
88 | return mDBReadable;
89 | }
90 |
91 | private static class DatabaseHelper extends SQLiteOpenHelper {
92 |
93 | // 这里的Context一定要用ApplicationContext
94 | private Context mContext = null;
95 |
96 | DatabaseHelper(Context context) {
97 | super(context, DATABASE_FILE, null, DBConfig.DB_VER);
98 | mContext = context;
99 | }
100 |
101 | @Override
102 | public void onCreate(SQLiteDatabase db) {
103 | // 创建+读入歌曲数据库表
104 | GLog.i(TAG, "[DatabaseHelper]CreateDB :");
105 | // 创建表,如果有新增字段必须进入CreateTable里面来加入新的字段
106 | createTable(db);
107 | }
108 |
109 | @Override
110 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
111 |
112 | }
113 |
114 | @Override
115 | public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
116 | try {
117 | GLog.i(TAG, "数据库降级 old:" + oldVersion + " newVersion:" + newVersion);
118 |
119 | //用来触发重新扫描
120 | } catch (Exception e) {
121 | GLog.e(TAG, e);
122 | }
123 | }
124 |
125 | private void createTable(SQLiteDatabase db) {
126 | //创建表
127 | db.execSQL("DROP TABLE IF EXISTS " + ContactInfoTable.CONTACT_INFO_TABLE);
128 | //创建表中具体的字段
129 | db.execSQL(ContactInfoTable.TABLE_CREATE);
130 | }
131 | }
132 | }
133 |
134 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/database/tables/ContactInfoTable.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.database.tables;
2 |
3 | import android.content.ContentValues;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.database.sqlite.SQLiteStatement;
7 |
8 | import com.android.androidtech.business.contact.ContactInfo;
9 |
10 | import java.util.ArrayList;
11 |
12 | /**
13 | * Created by yuchengluo on 2015/6/29.
14 | */
15 | public class ContactInfoTable extends BaseTable {
16 | private static String TAG = "ContactInfoTable";
17 | public static final String CONTACT_INFO_TABLE = "ContactInfo_table"; // 账户信息table
18 | private static final String KEY_CONTACT_ID = "contack_num";
19 | private static final String KEY_CONTACT_NAME = "contack_name";
20 | private static final String KEY_USER_PHONE_NUM = "contack_phonenumber";
21 | private SQLiteStatement mSQLiteStatement = null;
22 | public static final String TABLE_CREATE = "create table if not exists " + CONTACT_INFO_TABLE + " (" + KEY_CONTACT_ID
23 | + " LONG primary key , " + KEY_CONTACT_NAME + " TEXT," + KEY_USER_PHONE_NUM + " TEXT "
24 | + ");";
25 | public final String STR_INSERT_STATEMENT_CONTACTS = "insert into " + CONTACT_INFO_TABLE
26 | + "(" + KEY_CONTACT_ID
27 | + "," + KEY_CONTACT_NAME
28 | + "," + KEY_USER_PHONE_NUM
29 | + ") values(?,?,?)";
30 |
31 | /**
32 | * 构造函数
33 | *
34 | * @param context
35 | */
36 | public ContactInfoTable(Context context) {
37 | super(context);
38 | }
39 |
40 | @Override
41 | public String getTableName() {
42 | return CONTACT_INFO_TABLE;
43 | }
44 |
45 | @Override
46 | public String[] getAllKey() {
47 | return new String[]{
48 | CONTACT_INFO_TABLE + "." + KEY_CONTACT_ID,
49 | CONTACT_INFO_TABLE + "." + KEY_CONTACT_NAME,
50 | CONTACT_INFO_TABLE + "." + KEY_USER_PHONE_NUM
51 | };
52 | }
53 |
54 | @Override
55 | public SQLiteStatement getSQLiteStatement() {
56 | if (null == mSQLiteStatement) {
57 | mSQLiteStatement = getSqliteDB().compileStatement(STR_INSERT_STATEMENT_CONTACTS);
58 | }
59 | return mSQLiteStatement;
60 | }
61 |
62 | public boolean insertContactInfoForStat(ContactInfo info) {
63 | getSQLiteStatement().clearBindings();
64 | getSQLiteStatement().bindLong(1, info.getContactId());
65 | getSQLiteStatement().bindString(2, info.getContactName());
66 | getSQLiteStatement().bindString(3, info.getContactNum());
67 | return getSQLiteStatement().executeInsert() > 0;
68 | }
69 |
70 | public boolean insertContactInfo(ContactInfo info) {
71 | return getSqliteDB().insert(CONTACT_INFO_TABLE, null, transContactInfo(info)) > 0;
72 | }
73 |
74 | public boolean updateContactInfo(ContactInfo info) {
75 | return getSqliteDB().update(CONTACT_INFO_TABLE, transContactInfo(info), kv(KEY_CONTACT_ID, info.getContactId()), null) > 0;
76 | }
77 |
78 | public boolean deleteContactInfo(ContactInfo info) {
79 | return getSqliteDB().delete(CONTACT_INFO_TABLE, kv(KEY_CONTACT_ID, info.getContactId()), null) > 0;
80 | }
81 |
82 | public ArrayList getAllContacts() {
83 | ArrayList songList = new ArrayList();
84 | Cursor cursors = null;
85 | cursors = getSqliteDB().query(true,
86 | CONTACT_INFO_TABLE,
87 | new String[]{KEY_CONTACT_ID, KEY_CONTACT_NAME, KEY_USER_PHONE_NUM},
88 | null
89 | , null, null, null, null, null);
90 | if(null != cursors && cursors.moveToFirst()){
91 | do{
92 | songList.add(transContactCursor(cursors));
93 | }while(cursors.moveToNext());
94 | }
95 | return songList;
96 | }
97 | private ContactInfo transContactCursor(Cursor cursor){
98 | long id = cursor.getLong(cursor.getColumnIndex(KEY_CONTACT_ID));
99 | String name = cursor.getString(cursor.getColumnIndex(KEY_CONTACT_NAME));
100 | String number = cursor.getString(cursor.getColumnIndex(KEY_USER_PHONE_NUM));
101 | return new ContactInfo(id,name,number);
102 | }
103 | private ContentValues transContactInfo(ContactInfo info) {
104 | ContentValues value = new ContentValues();
105 | value.put(KEY_CONTACT_ID, info.getContactId());
106 | value.put(KEY_CONTACT_NAME, info.getContactName());
107 | value.put(KEY_USER_PHONE_NUM, info.getContactNum());
108 | return value;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/fragment/performance/memory/ImageGridFragment.java:
--------------------------------------------------------------------------------
1 |
2 | package com.android.androidtech.fragment.performance.memory;
3 |
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.view.animation.Animation;
10 | import android.widget.AbsListView;
11 | import android.widget.BaseAdapter;
12 | import android.widget.ImageView;
13 | import android.widget.ListView;
14 |
15 | import com.android.androidtech.R;
16 | import com.android.androidtech.fragment.base.BaseFragment;
17 | import com.android.miniimageloader.MiniImageLoader;
18 | import com.android.miniimageloader.config.BitmapConfig;
19 |
20 | public class ImageGridFragment extends BaseFragment {
21 | private static final String TAG = "ImageGridFragment";
22 | // private ImageWorker mImageWorker;
23 | private ImageAdapter mAdapter;
24 | @Override
25 | public void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 |
28 | // mImageWorker = new ImageFetcher(getActivity(), 50);
29 |
30 | // ImageCache.ImageCacheParams cacheParams = new ImageCache.ImageCacheParams();
31 | //
32 | // //
33 | // cacheParams.setMemCacheSizePercent(0.25f);
34 |
35 | // mImageWorker.initImageCache(getActivity().getSupportFragmentManager(), cacheParams);
36 | }
37 |
38 |
39 | @Override
40 | protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
41 | View v = inflater.inflate(R.layout.list, container, false);
42 | ListView listView = (ListView) v.findViewById(R.id.image_list);
43 | mAdapter = new ImageAdapter(getHostActivity());
44 | listView.setAdapter(mAdapter);
45 |
46 | listView.setOnScrollListener(new AbsListView.OnScrollListener() {
47 | @Override
48 | public void onScrollStateChanged(AbsListView absListView, int scrollState) {
49 |
50 | if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
51 | MiniImageLoader.getInstance().setPauseWork(true);
52 | } else {
53 | MiniImageLoader.getInstance().setPauseWork(false);
54 | }
55 | }
56 |
57 | @Override
58 | public void onScroll(AbsListView absListView, int firstVisibleItem,
59 | int visibleItemCount, int totalItemCount) {
60 | }
61 | });
62 |
63 | return v;
64 | }
65 |
66 | @Override
67 | protected void resume() {
68 | mAdapter.notifyDataSetChanged();
69 | }
70 |
71 | @Override
72 | protected void stop() {
73 |
74 | }
75 |
76 | @Override
77 | protected void pause() {
78 | }
79 |
80 | @Override
81 | protected void start() {
82 |
83 | }
84 |
85 | @Override
86 | public void onEnterAnimationEnd(Animation animation) {
87 |
88 | }
89 |
90 |
91 | @Override
92 | public void onDestroy() {
93 | super.onDestroy();
94 | }
95 |
96 | @Override
97 | public void clearView() {
98 |
99 | }
100 |
101 | @Override
102 | public void clear() {
103 |
104 | }
105 |
106 | @Override
107 | protected void initData(Bundle data) {
108 |
109 | }
110 |
111 | private class ImageAdapter extends BaseAdapter {
112 | private LayoutInflater mInflater;
113 |
114 | public ImageAdapter(Context context) {
115 | this.mInflater = LayoutInflater.from(context);
116 | }
117 |
118 | @Override
119 | public int getCount() {
120 | return Images.imageThumbUrls.length;
121 | }
122 |
123 | @Override
124 | public Object getItem(int position) {
125 | return null;
126 | }
127 |
128 | @Override
129 | public long getItemId(int position) {
130 | return 0;
131 | }
132 |
133 | @Override
134 | public View getView(int position, View convertView, ViewGroup parent) {
135 | ImageView imageView;
136 |
137 | if (convertView == null) {
138 | convertView = mInflater.inflate(R.layout.list_item, parent, false);
139 | imageView = (ImageView) convertView.findViewById(R.id.img);
140 | } else {
141 | imageView = (ImageView) convertView.findViewById(R.id.img);
142 | }
143 | MiniImageLoader.getInstance().loadImage(Images.imageThumbUrls[position], imageView,new BitmapConfig(50,50));
144 | return convertView;
145 | }
146 | }
147 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/activity/AppStartActivity.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.activity;
2 |
3 | /**
4 | * First activity.
5 | * */
6 | import android.animation.Animator;
7 | import android.animation.AnimatorSet;
8 | import android.animation.ObjectAnimator;
9 | import android.app.Activity;
10 | import android.content.Intent;
11 | import android.os.Bundle;
12 | import android.os.Handler;
13 | import android.os.Message;
14 | import android.view.View;
15 | import android.view.animation.Animation;
16 | import android.view.animation.AnimationSet;
17 | import android.view.animation.RotateAnimation;
18 | import android.view.animation.ScaleAnimation;
19 | import android.widget.ImageView;
20 |
21 | import com.android.androidtech.R;
22 | import com.android.androidtech.monitor.time.TimeMonitorConfig;
23 | import com.android.androidtech.monitor.time.TimeMonitorManager;
24 |
25 |
26 | public class AppStartActivity extends Activity {
27 |
28 | ImageView mLogo = null;
29 | private final int TIME_ANIMATION = 1500;
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | TimeMonitorManager.getInstance().getTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START).recodingTimeTag("AppStartActivity_create");
33 | super.onCreate(savedInstanceState);
34 |
35 | setContentView(R.layout.activity_app_start);
36 | mLogo = (ImageView) this.findViewById(R.id.logo);
37 | //mStartHandler.sendEmptyMessageDelayed(0,1000);
38 | // useAnimation();
39 | useAnimator();
40 | TimeMonitorManager.getInstance().getTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START).recodingTimeTag("AppStartActivity_createOver");
41 | }
42 |
43 | @Override
44 | protected void onStart() {
45 | super.onStart();
46 | TimeMonitorManager.getInstance().getTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START).end("AppStartActivity_start", false);
47 | }
48 |
49 | /*
50 | AlphaAnimation
51 | ScaleAnimation
52 | TranslateAnimation
53 | RotateAnimation
54 | * */
55 | private void useAnimation() {
56 | Animation mRota = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
57 | ScaleAnimation mScale = new ScaleAnimation(0.0f, 1f, 0.0f, 1f,
58 | Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
59 | mScale.setAnimationListener(new Animation.AnimationListener() {
60 | @Override
61 | public void onAnimationStart(Animation animation) {
62 |
63 | }
64 |
65 | @Override
66 | public void onAnimationEnd(Animation animation) {
67 | mStartHandler.sendEmptyMessageDelayed(0, 0);
68 | }
69 |
70 | @Override
71 | public void onAnimationRepeat(Animation animation) {
72 |
73 | }
74 | });
75 | AnimationSet animationSet = new AnimationSet(true);
76 | animationSet.addAnimation(mRota);
77 | animationSet.addAnimation(mScale);
78 | animationSet.setDuration(TIME_ANIMATION);
79 | mLogo.startAnimation(animationSet);
80 | }
81 |
82 | //AnimatorSet
83 | private void useAnimator() {
84 | mLogo.setLayerType(View.LAYER_TYPE_HARDWARE,null);
85 | ObjectAnimator scalex = ObjectAnimator.ofFloat(mLogo, "scaleX", 0, 1);
86 | ObjectAnimator scaley = ObjectAnimator.ofFloat(mLogo, "scaleY", 0, 1);
87 | ObjectAnimator rotation = ObjectAnimator.ofFloat(mLogo, "rotation", 0.0f, 360f);
88 | rotation.addListener(new ObjectAnimator.AnimatorListener() {
89 | @Override
90 | public void onAnimationStart(Animator animation) {
91 | }
92 |
93 | @Override
94 | public void onAnimationEnd(Animator animation) {
95 | mLogo.setLayerType(View.LAYER_TYPE_NONE,null);
96 | mStartHandler.sendEmptyMessageDelayed(0, 0);
97 | }
98 |
99 | @Override
100 | public void onAnimationCancel(Animator animation) {
101 | }
102 |
103 | @Override
104 | public void onAnimationRepeat(Animator animation) {
105 | }
106 | });
107 | AnimatorSet mSetPlayer = new AnimatorSet();
108 | mSetPlayer.setDuration(TIME_ANIMATION);
109 | mSetPlayer.play(scalex).with(scaley).with(rotation);
110 | mSetPlayer.start();
111 | }
112 |
113 | private Handler mStartHandler = new Handler() {
114 | @Override
115 | public void handleMessage(Message msg) {
116 | //test
117 | Intent it = new Intent(AppStartActivity.this, HomePageActivity.class);
118 | startActivity(it);
119 | finish();
120 | }
121 | };
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/monitor/ui/sampling/CpuInfoSampler.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.monitor.ui.sampling;
2 |
3 | import android.util.Log;
4 |
5 | import com.android.androidtech.utils.GLog;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.FileInputStream;
9 | import java.io.IOException;
10 | import java.io.InputStreamReader;
11 | import java.util.ArrayList;
12 |
13 | /**
14 | * Created by yuchengluo on 2016/4/1.
15 | */
16 | public class CpuInfoSampler extends BaseSampler {
17 | private final String TAG = "CpuInfoSampler";
18 | private int mPid = -1;
19 | private ArrayList mCpuInfoList = new ArrayList();
20 | public CpuInfoSampler() {
21 |
22 | }
23 | @Override
24 | void doSample() {
25 | GLog.d(TAG, "doSample");
26 | dumpCpuInfo();
27 | }
28 | @Override
29 | public void start() {
30 | super.start();
31 | mUserPre = 0;
32 | mSystemPre = 0;
33 | mIdlePre = 0;
34 | mIoWaitPre = 0;
35 | mTotalPre = 0;
36 | mAppCpuTimePre = 0;
37 | }
38 | public void clearCache(){
39 | mCpuInfoList.clear();
40 | }
41 | public ArrayList getStatCpuInfoList(){
42 | return mCpuInfoList;
43 | }
44 | private void dumpCpuInfo() {
45 | BufferedReader cpuReader = null;
46 | BufferedReader pidReader = null;
47 | try {
48 | cpuReader = new BufferedReader(new InputStreamReader(
49 | new FileInputStream("/proc/stat")), 1024);
50 | String cpuRate = cpuReader.readLine();
51 | if (cpuRate == null) {
52 | cpuRate = "";
53 | }
54 | if (mPid < 0) {
55 | mPid = android.os.Process.myPid();
56 | }
57 | pidReader = new BufferedReader(new InputStreamReader(
58 | new FileInputStream("/proc/" + mPid + "/stat")), 1024);
59 | String pidCpuRate = pidReader.readLine();
60 | if (pidCpuRate == null) {
61 | pidCpuRate = "";
62 | }
63 | parseCpuRate(cpuRate, pidCpuRate);
64 | } catch (Throwable ex) {
65 | Log.e(TAG, "doSample: ", ex);
66 | } finally {
67 | try {
68 | if (cpuReader != null) {
69 | cpuReader.close();
70 | }
71 | if (pidReader != null) {
72 | pidReader.close();
73 | }
74 | } catch (IOException e) {
75 | Log.e(TAG, "doSample: ", e);
76 | }
77 | }
78 | }
79 | private void parseCpuRate(String cpuRate, String pidCpuRate) {
80 | String[] cpuInfoArray = cpuRate.split(" ");
81 | if (cpuInfoArray.length < 9) {
82 | return;
83 | }
84 | long user_time = Long.parseLong(cpuInfoArray[2]);
85 | long nice_time = Long.parseLong(cpuInfoArray[3]);
86 | long system_time = Long.parseLong(cpuInfoArray[4]);
87 | long idle_time = Long.parseLong(cpuInfoArray[5]);
88 | long ioWait_time = Long.parseLong(cpuInfoArray[6]);
89 | long total_time = user_time + nice_time + system_time + idle_time + ioWait_time + Long.parseLong(cpuInfoArray[7]) + Long.parseLong(cpuInfoArray[8]);
90 | String[] pidCpuInfos = pidCpuRate.split(" ");
91 | if (pidCpuInfos.length < 17) {
92 | return;
93 | }
94 | long appCpu_time = Long.parseLong(pidCpuInfos[13]) + Long.parseLong(pidCpuInfos[14])
95 | + Long.parseLong(pidCpuInfos[15]) + Long.parseLong(pidCpuInfos[16]);
96 | if (mAppCpuTimePre > 0) {
97 | CpuInfo mCi = new CpuInfo(System.currentTimeMillis());
98 | long idleTime = idle_time - mIdlePre;
99 | long totalTime = total_time - mTotalPre;
100 | mCi.mCpuRate = (totalTime - idleTime) * 100L / totalTime;
101 | mCi.mAppRate = (appCpu_time - mAppCpuTimePre) * 100L / totalTime;
102 | mCi.mSystemRate = (system_time - mSystemPre) * 100L / totalTime;
103 | mCi.mUserRate = (user_time - mUserPre) * 100L / totalTime;
104 | mCi.mIoWait = (ioWait_time - mIoWaitPre) * 100L / totalTime;
105 | synchronized (mCpuInfoList) {
106 | mCpuInfoList.add(mCi);
107 | GLog.d(TAG,"cpu info :" + mCi.toString());
108 | }
109 | }
110 | mUserPre = user_time;
111 | mSystemPre = system_time;
112 | mIdlePre = idle_time;
113 | mIoWaitPre = ioWait_time;
114 | mTotalPre = total_time;
115 | mAppCpuTimePre = appCpu_time;
116 | }
117 | private long mUserPre = 0;
118 | private long mSystemPre = 0;
119 | private long mIdlePre = 0;
120 | private long mIoWaitPre = 0;
121 | private long mTotalPre = 0;
122 | private long mAppCpuTimePre = 0;
123 | }
124 |
--------------------------------------------------------------------------------
/miniimageloder/src/main/java/com/android/miniimageloader/ImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.android.miniimageloader;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.content.res.Resources;
6 | import android.graphics.Bitmap;
7 | import android.graphics.BitmapFactory;
8 | import android.graphics.drawable.BitmapDrawable;
9 | import android.graphics.drawable.Drawable;
10 | import android.media.Image;
11 | import android.os.Build;
12 | import android.widget.ImageView;
13 |
14 | import com.android.miniimageloader.cache.ImageCache;
15 | import com.android.miniimageloader.config.BitmapConfig;
16 |
17 | import java.io.InputStream;
18 | import java.lang.ref.WeakReference;
19 |
20 | /**
21 | * Created by yuchengluo on 2016/5/5.
22 | */
23 | public abstract class ImageLoader {
24 | private boolean mExitTasksEarly = false; // 是否提前退出的标志
25 | protected boolean mPauseWork = false;
26 | private final Object mPauseWorkLock = new Object();
27 | public final String TAG = "ImageLoader";
28 |
29 | protected ImageLoader() {
30 | Init();
31 | }
32 |
33 | private void Init() {
34 | }
35 |
36 | public void loadImage(String url, ImageView imageView, BitmapConfig bmConfig) {
37 | if (url == null) {
38 | return;
39 | }
40 | Bitmap bitmap = getmImageCache().getBitmap(url);;
41 | if (bitmap != null) {
42 | setImageBitmap(imageView,bitmap);
43 | }
44 | //否则走加载
45 | else {
46 |
47 | final BitmapLoadTask task = new BitmapLoadTask(url, imageView, bmConfig);
48 |
49 | task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR);
50 | }
51 | }
52 |
53 | private class BitmapLoadTask extends
54 | AsyncTask {
55 | private String mUrl;
56 | private BitmapConfig mBitmapConfig = null;
57 | private final WeakReference imageViewReference;
58 |
59 | public BitmapLoadTask(String url, ImageView imageView, BitmapConfig bmConfig) {
60 | mUrl = url;
61 | imageViewReference = new WeakReference(imageView);
62 | mBitmapConfig = bmConfig;
63 | }
64 |
65 | @Override
66 | protected Bitmap doInBackground(Void... params) {
67 | Bitmap bitmap = null;
68 | synchronized (mPauseWorkLock) {
69 | while (mPauseWork && !isCancelled()) {
70 | try {
71 | mPauseWorkLock.wait();
72 | } catch (InterruptedException e) {
73 | e.printStackTrace();
74 | }
75 | }
76 | }
77 | if (bitmap == null && !isCancelled()
78 | && imageViewReference.get() != null && !mExitTasksEarly) {
79 | bitmap = getmImageCache().getBitmapFromDisk(mUrl, mBitmapConfig);
80 | }
81 |
82 | if (bitmap == null && !isCancelled()
83 | && imageViewReference.get() != null && !mExitTasksEarly) {
84 | bitmap = downLoadBitmap(mUrl, mBitmapConfig);
85 | }
86 | if (bitmap != null) {
87 | getmImageCache().addToCache(mUrl, bitmap);
88 | }
89 |
90 | return bitmap;
91 | }
92 |
93 | @Override
94 | protected void onPostExecute(Bitmap result) {
95 | if (isCancelled() || mExitTasksEarly) {
96 | result = null;
97 | }
98 |
99 | ImageView imageView = imageViewReference.get();
100 | if (result != null && imageView != null) {
101 | setImageBitmap(imageView, result);
102 | }
103 | }
104 |
105 | @Override
106 | protected void onCancelled(Bitmap value) {
107 | super.onCancelled(value);
108 | synchronized (mPauseWorkLock) {
109 | mPauseWorkLock.notifyAll();
110 | }
111 | }
112 | }
113 |
114 | /**
115 | * @param imageView
116 | * @param drawable
117 | */
118 | private void setImageBitmap(ImageView imageView, Bitmap bitmap) {
119 | imageView.setImageBitmap(bitmap);
120 | }
121 |
122 | public void setPauseWork(boolean pauseWork) {
123 | synchronized (mPauseWorkLock) {
124 | mPauseWork = pauseWork;
125 | if (!mPauseWork) {
126 | mPauseWorkLock.notifyAll();
127 | }
128 | }
129 | }
130 |
131 | public void setExitTasksEarly(boolean exitTasksEarly) {
132 | mExitTasksEarly = exitTasksEarly;
133 | setPauseWork(false);
134 | }
135 |
136 | /**
137 | * 下载
138 | *
139 | * @param url
140 | * @return
141 | */
142 | protected abstract Bitmap downLoadBitmap(String url, BitmapConfig bmConfig);
143 |
144 | protected abstract ImageCache getmImageCache();
145 | }
146 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/fragment/performance/ui/ListViewFragment.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.fragment.performance.ui;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.view.animation.Animation;
9 | import android.widget.BaseAdapter;
10 | import android.widget.ImageView;
11 | import android.widget.ListView;
12 | import android.widget.TextView;
13 |
14 | import com.android.androidtech.R;
15 | import com.android.androidtech.fragment.base.BaseFragment;
16 |
17 | import java.util.ArrayList;
18 | import java.util.HashMap;
19 | import java.util.List;
20 |
21 | /**
22 | * Created by yuchengluo on 2015/8/5.
23 | */
24 | public class ListViewFragment extends BaseFragment {
25 |
26 | private List> mData;
27 | private ListView listView;
28 | private Context mContext;
29 | boolean bool = false;
30 | @Override
31 | protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
32 | mContext = getHostActivity();
33 | View view = inflater.inflate(R.layout.fm_listview, container, false);
34 | mData = getData();//为刚才的变量赋值
35 | MyAdapter adapter = new MyAdapter(mContext);//创建一个适配器
36 |
37 | listView = (ListView) view.findViewById(R.id.listView);//实例化ListView
38 | listView.setAdapter(adapter);//为ListView控件绑定适配器
39 | return view;
40 | }
41 |
42 | @Override
43 | protected void resume() {
44 |
45 | }
46 |
47 | @Override
48 | protected void stop() {
49 |
50 | }
51 |
52 | @Override
53 | protected void pause() {
54 |
55 | }
56 |
57 | @Override
58 | protected void start() {
59 |
60 | }
61 |
62 | @Override
63 | public void onEnterAnimationEnd(Animation animation) {
64 |
65 | }
66 |
67 | @Override
68 | public void clearView() {
69 |
70 | }
71 |
72 | @Override
73 | public void clear() {
74 |
75 | }
76 |
77 | @Override
78 | protected void initData(Bundle data) {
79 |
80 | }
81 |
82 | /**
83 | * 自定义适配器
84 | */
85 | public class MyAdapter extends BaseAdapter {
86 | private LayoutInflater mInflater;// 动态布局映射
87 |
88 | private class ItemHolder {
89 | TextView title;
90 | TextView time;
91 | TextView info;
92 | ImageView img;
93 | }
94 | public MyAdapter(Context context) {
95 | this.mInflater = LayoutInflater.from(context);
96 | }
97 |
98 | // 决定ListView有几行可见
99 | @Override
100 | public int getCount() {
101 | return mData.size();// ListView的条目数
102 | }
103 |
104 | @Override
105 | public Object getItem(int arg0) {
106 | return null;
107 | }
108 |
109 | @Override
110 | public long getItemId(int arg0) {
111 | return 0;
112 | }
113 |
114 | @Override
115 | public View getView(int position, View convertView, ViewGroup parent) {
116 | ItemHolder itemHolder = null;
117 | if(convertView == null) {
118 | convertView = mInflater.inflate(R.layout.item_listview_test, null);//根据布局文件实例化view
119 | itemHolder = new ItemHolder();
120 | itemHolder.title = (TextView) convertView.findViewById(R.id.title);//找某个控件
121 | itemHolder.time = (TextView) convertView.findViewById(R.id.time);//找某个控件
122 | itemHolder.info = (TextView) convertView.findViewById(R.id.info);
123 | itemHolder.img = (ImageView) convertView.findViewById(R.id.img);
124 | convertView.setTag(itemHolder);
125 | }else{
126 | itemHolder = (ItemHolder)convertView.getTag();
127 | }
128 | itemHolder.info.setText(mData.get(position).get("info").toString());
129 | itemHolder.time.setText(mData.get(position).get("time").toString());//给该控件设置数据(数据从集合类中来)
130 | itemHolder.title.setText(mData.get(position).get("title").toString());//给该控件设置数据(数据从集合类中来)
131 | itemHolder.img.setBackgroundResource((Integer) mData.get(position).get("img"));
132 | return convertView;
133 | }
134 | }
135 |
136 | // 初始化一个List
137 | private List> getData() {
138 | // 新建一个集合类,用于存放多条数据
139 | ArrayList> list = new ArrayList>();
140 | HashMap map = null;
141 | for (int i = 1; i <= 40; i++) {
142 | map = new HashMap();
143 | map.put("title", "姓名" + i);
144 | map.put("time", "08-05");
145 | map.put("info", "我通过了你的好友验证请求");
146 | map.put("img", R.mipmap.ic_launcher);
147 | list.add(map);
148 | }
149 |
150 | return list;
151 | }
152 |
153 | public void showInfo(int position) {
154 | getData();
155 | }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_homepage.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
19 |
20 |
25 |
26 |
36 |
37 |
38 |
42 |
43 |
46 |
47 |
57 |
58 |
68 |
69 |
70 |
81 |
82 |
86 |
87 |
97 |
98 |
108 |
109 |
110 |
114 |
115 |
121 |
122 |
123 |
128 |
129 |
--------------------------------------------------------------------------------
/miniimageloder/src/main/java/com/android/miniimageloader/cache/MemoryCache.java:
--------------------------------------------------------------------------------
1 | package com.android.miniimageloader.cache;
2 |
3 | import android.annotation.TargetApi;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.drawable.BitmapDrawable;
7 | import android.os.Build;
8 | import android.util.Log;
9 | import android.util.LruCache;
10 |
11 | import com.android.miniimageloader.utils.MLog;
12 |
13 | import java.lang.ref.SoftReference;
14 | import java.util.Collections;
15 | import java.util.HashSet;
16 | import java.util.Iterator;
17 | import java.util.Set;
18 |
19 | /**
20 | * Created by yuchengluo on 2016/5/12.
21 | */
22 | public class MemoryCache{
23 | private final int DEFAULT_MEM_CACHE_SIZE = 1024 * 12;
24 | private LruCache mMemoryCache;
25 | private Set> mReusableBitmaps;
26 | private final String TAG = "MemoryCache";
27 |
28 | public MemoryCache(float sizePer){
29 | Init(sizePer);
30 | }
31 | private void Init(float sizePer){
32 | int cacheSize = DEFAULT_MEM_CACHE_SIZE;
33 | if(sizePer> 0){
34 | cacheSize = Math.round(sizePer * Runtime.getRuntime().maxMemory() / 1024);
35 | }
36 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
37 | mReusableBitmaps =
38 | Collections.synchronizedSet(new HashSet>());
39 | }
40 | mMemoryCache = new LruCache(cacheSize){
41 | @Override
42 | protected int sizeOf(String key, Bitmap value) {
43 | final int bitmapSize = getBitmapSize(value) / 1024;
44 | return bitmapSize == 0 ? 1 : bitmapSize;
45 | }
46 |
47 | @Override
48 | protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
49 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
50 | mReusableBitmaps.add(new SoftReference(oldValue));
51 | }
52 | }
53 | };
54 | }
55 |
56 | @TargetApi(Build.VERSION_CODES.KITKAT)
57 | public int getBitmapSize(Bitmap bitmap) {
58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
59 | return bitmap.getAllocationByteCount();
60 | }
61 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
62 | return bitmap.getByteCount();
63 | }
64 | return bitmap.getRowBytes() * bitmap.getHeight();
65 | }
66 | @TargetApi(Build.VERSION_CODES.KITKAT)
67 | private static boolean canUseForInBitmap(
68 | Bitmap candidate, BitmapFactory.Options targetOptions) {
69 |
70 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
71 | return candidate.getWidth() == targetOptions.outWidth
72 | && candidate.getHeight() == targetOptions.outHeight
73 | && targetOptions.inSampleSize == 1;
74 | }
75 | int width = targetOptions.outWidth / targetOptions.inSampleSize;
76 | int height = targetOptions.outHeight / targetOptions.inSampleSize;
77 |
78 | int byteCount = width * height * getBytesPerPixel(candidate.getConfig());
79 |
80 | return byteCount <= candidate.getAllocationByteCount();
81 | }
82 | private static int getBytesPerPixel(Bitmap.Config config) {
83 | if (config == Bitmap.Config.ARGB_8888) {
84 | return 4;
85 | } else if (config == Bitmap.Config.RGB_565) {
86 | return 2;
87 | } else if (config == Bitmap.Config.ARGB_4444) {
88 | return 2;
89 | } else if (config == Bitmap.Config.ALPHA_8) {
90 | return 1;
91 | }
92 | return 1;
93 | }
94 | //获取inBitmap,实现内存复用
95 | public Bitmap getBitmapFromReusableSet(BitmapFactory.Options options) {
96 | Bitmap bitmap = null;
97 |
98 | if (mReusableBitmaps != null && !mReusableBitmaps.isEmpty()) {
99 | final Iterator> iterator = mReusableBitmaps.iterator();
100 | Bitmap item;
101 |
102 | while (iterator.hasNext()) {
103 | item = iterator.next().get();
104 |
105 | if (null != item && item.isMutable()) {
106 | if (canUseForInBitmap(item, options)) {
107 |
108 | Log.v("TEST", "canUseForInBitmap!!!!");
109 |
110 | bitmap = item;
111 |
112 | // Remove from reusable set so it can't be used again
113 | iterator.remove();
114 | break;
115 | }
116 | } else {
117 | // Remove from the set if the reference has been cleared.
118 | iterator.remove();
119 | }
120 | }
121 | }
122 |
123 | return bitmap;
124 | }
125 | public Bitmap getBitmap(String url) {
126 | Bitmap bitmap = null;
127 | if (mMemoryCache != null) {
128 | bitmap = mMemoryCache.get(url);
129 | }
130 | if (bitmap != null) {
131 | MLog.d(TAG, "Memory cache EXIET!");
132 | }
133 | return bitmap;
134 | }
135 | public void addBitmapToCache(String url,Bitmap bitmap) {
136 | if (url == null || bitmap == null) {
137 | return;
138 | }
139 | MLog.d(TAG,"addBitmapToCache size:" + getBitmapSize(bitmap));
140 | mMemoryCache.put(url, bitmap);
141 | }
142 | public void clearCache() {
143 | if (mMemoryCache != null) {
144 | mMemoryCache.evictAll();
145 | }
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/androidtech/fragment/performance/memory/BitmapMemeryFragment.java:
--------------------------------------------------------------------------------
1 | package com.android.androidtech.fragment.performance.memory;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.view.animation.Animation;
10 | import android.widget.ImageView;
11 | import android.widget.TextView;
12 |
13 | import com.android.androidtech.GmfApplication;
14 | import com.android.androidtech.R;
15 | import com.android.androidtech.fragment.base.BaseFragment;
16 | import com.android.androidtech.utils.GLog;
17 |
18 | import java.io.IOException;
19 | import java.io.InputStream;
20 |
21 | /**
22 | * Created by yuchengluo on 2015/11/17.
23 | */
24 | public class BitmapMemeryFragment extends BaseFragment {
25 |
26 | ImageView mImageview = null;
27 | TextView mTexBm = null;
28 | private final String TAG = "BitmapMemeryFragment";
29 | @Override
30 | protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
31 | View v = inflater.inflate(R.layout.layout_bitmap_show, container, false);
32 | mImageview = (ImageView) v.findViewById(R.id.viewstub_demo_imageview);
33 | mTexBm = (TextView) v.findViewById(R.id.text_bm_mem);
34 | showBitMap();
35 | // testMemeny();
36 | return v;
37 | }
38 | Bitmap[] mBitmap = null;
39 | private void testMemeny() {
40 | mBitmap = new Bitmap[10];
41 | new Thread() {
42 | public void run() {
43 | InputStream in = null;
44 | try {
45 | for (int i = 0; i < 10; i++) {
46 | Thread.sleep(2000);
47 |
48 | in = GmfApplication.getContext().getResources().getAssets().open("jpg_1920_1080.jpg");
49 | BitmapFactory.Options opts = getSampledBitmapOptionsFromStream(in, 1080, 1080);
50 |
51 | mBitmap[i] = BitmapFactory.decodeStream(in, null, opts);
52 | GLog.d(TAG,"testMemeny:" + i + "||size:" + mBitmap[i].getByteCount());
53 | }
54 | } catch (IOException e) {
55 | e.printStackTrace();
56 | } catch (InterruptedException e) {
57 | e.printStackTrace();
58 | }
59 | }
60 | }.start();
61 | }
62 |
63 | private void showBitMap() {
64 | InputStream in = null;
65 | try {
66 | in = GmfApplication.getContext().getResources().getAssets().open("jpg_1920_1080.jpg");
67 | if (null == in) {
68 | return;
69 | }
70 | BitmapFactory.Options opts = getSampledBitmapOptionsFromStream(in, 1080, 1080);
71 | Bitmap bitmap = BitmapFactory.decodeStream(in, null, opts);
72 | // Bitmap bitmap = BitmapFactory.decodeStream(in);
73 | if (null != bitmap) {
74 | mImageview.setImageBitmap(bitmap);
75 | mTexBm.setText("Bitmap.565&inSam:" + bitmap.getByteCount());
76 | GLog.d(TAG, "||size:" + bitmap.getByteCount());
77 | }
78 | } catch (IOException e) {
79 | e.printStackTrace();
80 | } finally {
81 | if (in != null) {
82 | try {
83 | in.close();
84 | } catch (IOException e) {
85 | e.printStackTrace();
86 | }
87 | }
88 | }
89 | }
90 |
91 |
92 | public static BitmapFactory.Options getSampledBitmapOptionsFromStream(
93 | InputStream is, int reqWidth, int reqHeight) {
94 | final BitmapFactory.Options options = new BitmapFactory.Options();
95 | options.inJustDecodeBounds = true;
96 | BitmapFactory.decodeStream(is, null, options);
97 | options.inPreferredConfig = Bitmap.Config.RGB_565;
98 | // 计算缩放比例
99 | options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
100 | options.inJustDecodeBounds = false;
101 |
102 | return options;
103 | }
104 |
105 | /**
106 | * @param @param options
107 | * @param @param reqWidth
108 | * @param @param reqHeight
109 | * @param @return
110 | * @return int 缩小的比例
111 | * @throws
112 | * @Description: 计算图片缩放比例
113 | */
114 | public static int calculateInSampleSize(BitmapFactory.Options options,
115 | int reqWidth, int reqHeight) {
116 |
117 | final int height = options.outHeight;
118 | final int width = options.outWidth;
119 | int inSampleSize = 1;
120 |
121 | if (height > reqHeight || width > reqWidth) {
122 |
123 | final int halfHeight = height / 2;
124 | final int halfWidth = width / 2;
125 |
126 | while ((halfHeight / inSampleSize) > reqHeight
127 | && (halfWidth / inSampleSize) > reqWidth) {
128 | inSampleSize *= 2;
129 | }
130 | }
131 | return inSampleSize;
132 | }
133 |
134 | @Override
135 | protected void resume() {
136 |
137 | }
138 |
139 | @Override
140 | protected void stop() {
141 |
142 | }
143 |
144 | @Override
145 | protected void pause() {
146 |
147 | }
148 |
149 | @Override
150 | protected void start() {
151 |
152 | }
153 |
154 | @Override
155 | public void onEnterAnimationEnd(Animation animation) {
156 |
157 | }
158 |
159 | @Override
160 | public void clearView() {
161 |
162 | }
163 |
164 | @Override
165 | public void clear() {
166 |
167 | }
168 |
169 | @Override
170 | protected void initData(Bundle data) {
171 |
172 | }
173 | }
174 |
--------------------------------------------------------------------------------