Android开发中,那些让你觉得相见恨晚的方法、类或接口
本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法、类或接口?,其实有一部是JAVA的,但是在android开发中也算常见。大多数的函数自己还是见过的,这里记录一下备忘。同时呢,也推荐一个github项目,里面记录了自己日常开发中见过的比较有用的东西开发中常用的工具、链接- Throwable类中的getStackTrace()方法,根据这个方法可以得到函数的逐层调用地址,其返回值为StackTraceElement[],而在StackTraceElement类中有四个方法getClassName(),getFileName(),getLineNumber(),getMethodName()在调试程序打印Log时非常有用。
- try {
- int num = 1 / 0;
- } catch (Exception e) {
- e.printStackTrace();
- StackTraceElement[] stackTrace = e.getStackTrace();
- for (StackTraceElement element : stackTrace) {
- String className = element.getClassName();
- int lineNumber = element.getLineNumber();
- String fileName = element.getFileName();
- String methodName = element.getMethodName();
- Log.e("TAG","fileName:"+fileName+" lineNumber:"+lineNumber+" className:"+className+" methodName"+methodName);
- }
- }
- UncaughtExceptionHandler接口,再好的代码异常难免,利用此接口可以处理未捕获的异常。比如NullPointerException空指针异常抛出时,用户没有try catch捕获,那么,Android系统会弹出对话框的“XXX程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。
- /**
- * 异常处理类
- * User:lizhangqu(513163535@qq.com)
- * Date:2015-08-04
- * Time: 14:48
- */
- public class CrashHandler implements Thread.UncaughtExceptionHandler {
- private static final String TAG = CrashHandler.class.getSimpleName();
- private Context mContext;
- private static volatile CrashHandler instance;
- private Thread.UncaughtExceptionHandler defalutHandler;
- private DateFormat formatter = new SimpleDateFormat(
- "yyyy-MM-dd_HH-mm-ss.SSS", Locale.CHINA);
- private CrashHandler(){
- }
- /**
- * 获得单例
- * @return 单例
- */
- public static CrashHandler getInstance() {
- if (instance==null){
- synchronized (CrashHandler.class){
- if (instance==null){
- instance=new CrashHandler();
- }
- }
- }
- return instance;
- }
- public void init(Context context){
- mContext=context.getApplicationContext();
- defalutHandler=Thread.getDefaultUncaughtExceptionHandler();
- // 获取系统默认的UncaughtException处理器
- Thread.setDefaultUncaughtExceptionHandler(this);
- // 设置该CrashHandler为程序的默认处理器
- }
- @Override
- public void uncaughtException(Thread thread, Throwable ex) {
- boolean hasHandle=handleException(ex);
- //是否处理
- if (!hasHandle && defalutHandler!=null){
- defalutHandler.uncaughtException(thread,ex);
- //如果用户没有处理则让系统默认的异常处理器来处理
- }else{
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- Log.e(TAG, "error : ", e);
- }
- android.os.Process.killProcess(android.os.Process.myPid());
- System.exit(1);
- }
- }
- private boolean handleException(final Throwable ex){
- if (ex==null){
- return false;
- }
- new Thread(){
- @Override
- public void run() {
- Looper.prepare();
- ex.printStackTrace();
- String err="["+ex.getMessage()+"]";
- Toast.makeText(mContext, "程序出现异常,5秒后自动退出", Toast.LENGTH_LONG).show();
- Looper.loop();
- }
- }.start();
- String str = collectDeviceInfo(ex);
- // 收集设备参数信息,日志信息
- saveCrashInfoToFile(str);
- // 保存日志文件
- return true;
- }
- /**
- * 收集设备信息,日志信息
- * @param ex Throwable
- * @return 收集的信息
- */
- private String collectDeviceInfo(Throwable ex){
- Log.e(TAG,"collectDeviceInfo:"+ex.getMessage());
- StringBuilder builder=new StringBuilder();
- return builder.toString();
- }
- /**
- * 保存出错信息
- * @param error 待保存的出错信息
- */
- private void saveCrashInfoToFile(String error){
- Log.e(TAG,"saveCrashInfoToFile:"+error);
- }
- }
- CrashHandler.getInstance().init(this);
- Resources类中的getIdentifier(name, defType, defPackage)方法,根据资源名称获取其ID,做UI时经常用到。
- /**
- * 根据资源名获得资源id
- * User:lizhangqu(513163535@qq.com)
- * Date:2015-08-04
- * Time: 15:18
- */
- public class ResourcesUtil {
- public static final String LAYTOUT="layout";
- public static final String DRAWABLE="drawable";
- public static final String MIPMAP="mipmap";
- public static final String MENU="menu";
- public static final String RAW="raw";
- public static final String ANIM="anim";
- public static final String STRING="string";
- public static final String STYLE="style";
- public static final String STYLEABLE="styleable";
- public static final String INTEGER="integer";
- public static final String ID="id";
- public static final String DIMEN="dimen";
- public static final String COLOR="color";
- public static final String BOOL="bool";
- public static final String ATTR="attr";
- //TODO please add other strings by yourself
- public static int getResourceId(Context context,String name,String type){
- Resources resources=null;
- PackageManager pm=context.getPackageManager();
- try {
- resources=context.getResources();
- return resources.getIdentifier(name, type, context.getPackageName());
- } catch (Exception e) {
- e.printStackTrace();
- }
- return 0;
- }
- }
- ResourcesUtil.getResourceId(getApplicationContext(),"activity_main",ResourcesUtil.LAYTOUT);
- View中的isShown()方法,以前都是用view.getVisibility() == View.VISIBLE来判断的,但是与这个函数还是有区别的。也就是只有当view本身和它的所有父容器都是visible时,isShown()才返回TRUE。而平常我们调用if(view.getVisibility() == View.VISIBLE)只是对view本身而不对父容器的可见性进行判断。
- 集合与数组的转化,Arrays类中的asList(T… array)方法,数组转List集合;反过来List.toArray();
- android.text.format.Formatter类中formatFileSize(Context, long)方法,用来格式化文件大小(B → KB → MB → GB)
- android.text.format.Formatter.formatFileSize(getApplicationContext(),1024);
- //返回1.00KB
- android.text.format.Formatter.formatFileSize(getApplicationContext(),1024*1024)
- //返回1.00MB
- android.media.ThumbnailUtils类,用来获取媒体(图片、视频)缩略图,该类从Android 2.2开始系统新增,不向下兼容
- /**
- * 创建一张视频的缩略图
- * 如果视频已损坏或者格式不支持可能返回null
- *
- * @param filePath 视频文件路径 如:/sdcard/android.3gp
- * @param kind kind可以为MINI_KIND或MICRO_KIND
- *
- */
- ThumbnailUtils.createVideoThumbnail(filePath,kind);
- /**
- *
- * 创建一个指定大小的缩略图
- * @param source 源文件(Bitmap类型)
- * @param width 压缩成的宽度
- * @param height 压缩成的高度
- */
- ThumbnailUtils.extractThumbnail(source , width, height);
- /**
- * 创建一个指定大小居中的缩略图
- *
- * @param source 源文件(Bitmap类型)
- * @param width 输出缩略图的宽度
- * @param height 输出缩略图的高度
- * @param options 如果options定义为OPTIONS_RECYCLE_INPUT,则回收@param source这个资源文件
- * (除非缩略图等于@param source)
- *
- */
- ThumbnailUtils.extractThumbnail(source , width, height,options);
- 格式化字符串,可以使用String类的format(String,Object…)方法,如果要格式化资源文件strings.xml中的字符串,可以使用getResources().getString(int,Object…)方法
- String.format("money:¥%.2f",1.00);
- <resources>
- <string name="format">money:$%.2f</string>
- </resources>
- getResources().getString(R.string.format,1.00);
- View类中的三个方法:callOnClick(),performClick(),performLongClick(),可以直接用于触发View的点击事件,不用我们手动点击才触发;
- findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Log.e("TAG", "onClick");
- }
- });
- findViewById(R.id.btn).setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- Log.e("TAG", "onLongClick");
- return true;
- }
- });
- findViewById(R.id.btn).callOnClick();
- findViewById(R.id.btn).performClick();
- findViewById(R.id.btn).performLongClick();
- /**
- * Call this view's OnClickListener, if it is defined. Performs all normal
- * actions associated with clicking: reporting accessibility event, playing
- * a sound, etc.
- *
- * @return True there was an assigned OnClickListener that was called, false
- * otherwise is returned.
- */
- public boolean performClick() {
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- ListenerInfo li = mListenerInfo;
- if (li != null && li.mOnClickListener != null) {
- playSoundEffect(SoundEffectConstants.CLICK);
- li.mOnClickListener.onClick(this);
- return true;
- }
- return false;
- }
- /**
- * Directly call any attached OnClickListener. Unlike {@link #performClick()},
- * this only calls the listener, and does not do any associated clicking
- * actions like reporting an accessibility event.
- *
- * @return True there was an assigned OnClickListener that was called, false
- * otherwise is returned.
- */
- public boolean callOnClick() {
- ListenerInfo li = mListenerInfo;
- if (li != null && li.mOnClickListener != null) {
- li.mOnClickListener.onClick(this);
- return true;
- }
- return false;
- }
- TextUtils类中的isEmpty(String)方法,判断字符串是否为null或”“,不要再自己写判断字符串非空的代码了。
- String str = null;
- String str1 = "";
- String str2 = "a";
- Log.e("TAG", TextUtils.isEmpty(str)+" "+TextUtils.isEmpty(str1)+" "+TextUtils.isEmpty(str2));
- //输出true true false
- TextView类中的append(String)方法,添加文本,不要再使用getText()方法拿到旧的字符串再拼接,拼接好了之后再调用setText()方法了
- TextView textview= (TextView) findViewById(R.id.tv);
- textview.setText("aaa");
- textview.append("bbb");
- View类中的getDrawingCache()等一系列方法,目前只知道可以用来截图
- /**
- * / 获取指定Activity的截屏,保存到png文件
- *
- * @param activity activity
- * @return 截屏Bitmap
- */
- private static Bitmap takeScreenShot(Activity activity) {
- // View是你需要截图的View
- View view = activity.getWindow().getDecorView();
- view.setDrawingCacheEnabled(true);
- view.buildDrawingCache();
- Bitmap b1 = view.getDrawingCache();
- // 获取状态栏高度
- Rect frame = new Rect();
- activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
- int statusBarHeight = frame.top;
- Log.i("TAG", "" + statusBarHeight);
- // 获取屏幕长和高
- int width = activity.getWindowManager().getDefaultDisplay().getWidth();
- int height = activity.getWindowManager().getDefaultDisplay()
- .getHeight();
- Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
- - statusBarHeight);
- view.destroyDrawingCache();
- return b;
- }
- DecimalFormat类,用于字串格式化包括指定位数、百分数、科学计数法等
- DecimalFormat df=new DecimalFormat("0.0");
- df.format(12.34);
- System类中的arraycopy(src, srcPos, dest, destPos, length)方法,用来copy数组;Arrays.copyOf()里的一系列方法也是间接调用System.arraycopy()方法
- Fragment类中的onHiddenChanged(boolean)方法,使用FragmentTransaction中的hide(),show()时貌似Fragment的其它生命周期方法都不会被调用
- @Override
- public void onHiddenChanged(boolean hidden) {
- super.onHiddenChanged(hidden);
- if(hidden){
- this.onPause();
- }else{
- this.onResume();
- }
- }
- Activity类中的onWindowFocusChanged(boolean)方法,使用一个view的getWidth() getHeight() 方法来获取该view的宽和高,返回的值却为0。
- 如果这个view的长宽很确定不为0的话,那很可能是你过早的调用这些方法,也就是说在这个view被加入到rootview之前你就调用了这些方法,返回的值自然为0.,解决该问题的方法有很多,主要就是延后调用这些方法。可以试着在onWindowFocusChanged()里面调用这些方法。
- View类中的getLocationInWindow(int[])方法和getLocationOnScreen(int[])方法,获取View在窗口/屏幕中的位置
- TextView tv= (TextView) findViewById(R.id.tv);
- int loc[]=new int[2];
- tv.getLocationInWindow(loc);
- Log.e("TAG",loc[0]+" "+loc[1]);
- TextView类中的setTransformationMethod(TransformationMethod)方法,可用来实现“显示密码”功能;
- TextView tv= (TextView) findViewById(R.id.tv);
- tv.setText("123456");
- tv.setTransformationMethod(PasswordTransformationMethod.getInstance());
- TextWatcher接口,用来监听文本输入框内容的改变,可以做的事很多
- View类中的setSelected(boolean)方法结合android:state_selected=”“用来实现图片选中效果
- Surface设置透明,但是会挡住其它控件
- SurfaceView.setZOrderOnTop(true);
- SurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
- LayoutInflater.from(getApplicationContext()).inflate(int resource, ViewGroup root, boolean attachToRoot)
- String abcd = PhoneNumberUtils.convertKeypadLettersToDigits("abcd");
- Log.e("TAG",abcd);
- //结果为2223
- public Object evaluate(float fraction, Object startValue, Object endValue) {
- int startInt = (Integer) startValue;
- int startA = (startInt >> 24) & 0xff;
- int startR = (startInt >> 16) & 0xff;
- int startG = (startInt >> 8) & 0xff;
- int startB = startInt & 0xff;
- int endInt = (Integer) endValue;
- int endA = (endInt >> 24) & 0xff;
- int endR = (endInt >> 16) & 0xff;
- int endG = (endInt >> 8) & 0xff;
- int endB = endInt & 0xff;
- return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
- (int)((startR + (int)(fraction * (endR - startR))) << 16) |
- (int)((startG + (int)(fraction * (endG - startG))) << 8) |
- (int)((startB + (int)(fraction * (endB - startB))));
- }
- //将一个style的parent设置为@android:style/Theme.Dialog
- //修改其中的 <item name="android:textSize">30sp</item>
- //利用context和该style生成ContextThemeWrapper
- //利用ContextThemeWrapper生产Builder对象
- ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(MainActivity.this, R.style.dialog);
- AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);
- Dialog dialog=builder.create();
- <Space
- android:layout_width="match_parent"
- android:layout_height="10dp"/>
- android.text.format.DateUtils.formatDateTime(getApplicationContext(),System.currentTimeMillis(), DateUtils.FORMAT_SHOW_DATE|DateUtils.FORMAT_SHOW_YEAR|DateUtils.FORMAT_SHOW_TIME);
- TextView tv= (TextView) findViewById(R.id.tv);
- Linkify.addLinks(tv,Linkify.WEB_URLS);
- public class BlankFragment extends Fragment {
- private static final String ARG_PARAM1 = "param1";
- private static final String ARG_PARAM2 = "param2";
- private String mParam1;
- private String mParam2;
- public static BlankFragment newInstance(String param1, String param2) {
- BlankFragment fragment = new BlankFragment();
- Bundle args = new Bundle();
- args.putString(ARG_PARAM1, param1);
- args.putString(ARG_PARAM2, param2);
- fragment.setArguments(args);
- return fragment;
- }
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (getArguments() != null) {
- mParam1 = getArguments().getString(ARG_PARAM1);
- mParam2 = getArguments().getString(ARG_PARAM2);
- }
- }
- }
- /**
- * 全局Application基类
- * User:lizhangqu(513163535@qq.com)
- * Date:2015-07-22
- * Time: 09:35
- */
- public class BaseApplication extends Application {
- public final static String ACTION_EXIT_APP = "package.exit";
- private static LocalBroadcastManager mLocalBroadcatManager;
- private static Context mContext;
- private static BaseApplication instance;
- public static Context getContext() {
- return mContext;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- instance = this;
- mContext = this.getApplicationContext();
- CorePageManager.getInstance().init(this);
- }
- /**
- * 发送本地广播退出程序
- */
- public void exitApp() {
- Intent intent = new Intent();
- intent.setAction(ACTION_EXIT_APP);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- BaseApplication.getLocalBroadcastManager().sendBroadcast(intent);
- BaseActivity.unInit();
- }
- /**
- * 获得LocalBroadcastManager对象
- * @return LocalBroadcastManager对象
- */
- public static LocalBroadcastManager getLocalBroadcastManager() {
- if (mLocalBroadcatManager == null) {
- mLocalBroadcatManager = LocalBroadcastManager.getInstance(mContext);
- }
- return mLocalBroadcatManager;
- }
- }
- public class BaseActivity extends FragmentActivity{
- public final static String ACTION_EXIT_APP = "package.exit";
- /**
- * 仅用于接受应用退出广播,程序退出时有机会做一些必要的清理工作
- */
- private BroadcastReceiver mExitReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(ACTION_EXIT_APP)) {
- Log.d(TAG,"exit from broadcast");
- finish();
- }
- }
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_base);
- IntentFilter filter = new IntentFilter();
- filter.addAction(Config.ACTION_EXIT_APP);
- filter.addCategory(Intent.CATEGORY_DEFAULT);
- BaseApplication.getLocalBroadcastManager().registerReceiver(mExitReceiver, filter);
- //注册本地广播,接收程序退出广播
- }
- }
- @Override
- protected void onResume() {
- super.onResume();
- //TODO 处理和统计代码
- Log.v(TAG, "onResume");
- Logger.v(TAG, "onResume");
- Logging.v(TAG, "onResume");
- ...
- }
- public void onCreate() {
- super.onCreate();
- this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
- @Override
- public void onActivityStopped(Activity activity) {
- Logger.v(activity, "onActivityStopped");
- }
- @Override
- public void onActivityStarted(Activity activity) {
- Logger.v(activity, "onActivityStarted");
- }
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
- Logger.v(activity, "onActivitySaveInstanceState");
- }
- @Override
- public void onActivityResumed(Activity activity) {
- Logger.v(activity, "onActivityResumed");
- }
- @Override
- public void onActivityPaused(Activity activity) {
- Logger.v(activity, "onActivityPaused");
- }
- @Override
- public void onActivityDestroyed(Activity activity) {
- Logger.v(activity, "onActivityDestroyed");
- }
- @Override
- public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
- Logger.v(activity, "onActivityCreated");
- }
- });
- };
- buildTypes {
- release {
- versionNameSuffix "sample"
- }
- }
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mPageSelectedListener = (PageSelectedListener) activity;
- mMenuBtnOnclickListener = (MenuBtnOnClickListener) activity;
- mCommitBtnOnClickListener = (CommitBtnOnClickListener) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + "must implements listener");
- }
- }
- Bitmap bm = Bitmap.createBitmap((int) (w * scale), (int) (h*scale), Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas();
- canvas.setBitmap(bm);
- View.draw(canvas);
- return bm;
自己偶然间发现的,拿出来让更多人知道自己也记录下,免得忘记。