Android Development - Summary of Tips 2

  1. When starting the virtual machine, there is a wipe user data in the launch options window. Checking it will make the virtual machine [restore factory settings]

2. [If you want your application to have multiple startup icons:]

为一个应用的 多个Activity都设置该过滤器,使之都成为优先启动的Activity,并且为这几个Activity设置icon,与 label属性

				那么部署后将发现手机中会有多个图标(icon与label都不同),但是实际上只有一个应用程序。

该过滤器写法:				
		<intent-filter>
        	<action android:name="android.intent.action.MAIN" />
        	<category android:name="android.intent.category.LAUNCHER" />
    	</intent-filter>


【如果想让自己的应用程序没有 任何页面且没有启动图标(隐秘):】    	

 	将清单文件的所有Action都去掉这个过滤器:   

	 	   <intent-filter>
	        	<action android:name="android.intent.action.MAIN" />
	        	<category android:name="android.intent.category.LAUNCHER" />
	    	</intent-filter>

注意:在安装4.0之后,如果安装的程序没有任何页面,则他所设置的广播接收器就不会生效。---安全性提高了

  1. -------- Implicit intent ---------

    [open phone dialer]

     /*  -------简写-------	
         Uri uri = Uri.parse("tel:119");
     	Intent intent = new Intent(Intent.ACTION_DIAL_DIAL,uri);
     	startActivity(intent);
     */
    	
     /*  -------详细---------
     	Intent intent = new Intent();
     	intent.setAction(Intent.ACTION_DIAL);
     	intent.setData(Uri.parse("tel:119"));
     	startActivity(intent);*/
    

4.---------Display intent---------

[Activity跳转--启动一个Activity]
	
	Intent intent = new integerent();	//new Intent(MainActivity.this, SecondActivity.class); 这样写则无需 setClass()
	intent.setClass(MainActivity.this, SecondActivity.class);
    startActivity(intent);		
  1. string.getBytes(String charsetName) ; //Use the specified character set (encoding method), encode the string into a byte array, and return

6.----------------------------------【Activity two startup methods, four startup modes】- ---------------------------------------------
【Activity two startup methods】 :

	普通方式:startActivity(intent);

	另一种方式:startActivityForResult(intent,requestCode); //【如果需要获得 目标Activity关闭时的 回传数据,则用这种方式】

							//此处的 for 可以翻译为:为了,即:开启一个Activity为了得到结果

[Activity's four startup modes]:

	1.清单文件-->Activity节点有:android:launchMode属性.用于标识Activity的启动模式

	2.有四个取值分别为:	standard 	 : 标准模式--【默认】,如果此Activity重复打开多次,则就会重复进栈
				
							singleTop 	 : 单顶模式 ----开启此Activity前会检查 栈顶,如果二者相同则复用栈顶,而不是重新压栈
															(在栈顶之下可以重复存在)
						
							singleTask   : 单任务模式---开启Activity时,会检查任务栈中是否有相同的Activity,若有则复用。
														且被复用的Activity上方的其他Activity都会被销毁,但下方的不影响。
															(此Activity在整个栈中都只有一份)

							singleInstance :单任务栈模式--开启此Activity时,会单独创建一个任务栈--且独享,再开则复用							(如果在其他模式的Activity上打开此Activity则会携带整个任务栈位于前部)
															--例如:来电界面

7. A normal running Activity suddenly switches to a horizontal or vertical screen: [will be destroyed first and then created] onPause–>onStop–>onDestroy–>onCreate–>onStart–>onResume

      【因此Activity的横竖屏方向 最好是在清单文件中设置好  】
      【 或者设置Activity属性 android:configChanges="orientation|keyboardHidden|screenSize"】

8. Using the include tag in the xml layout file can refer to other layout files at the specified position of this layout file:

	例:
	   <include 
	    	android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
        layout="@layout/activity_find"
        />   

-------------------------[Click a button to pop up several forms of menus] – OptionMenu, ContextMenu, PopupMenu ------ ---------------------------

9. Click a button in Android to pop up optionMenu (options menu). Just call Activity.this.openOptionsMenu(); method

	例:myButton.setOnClickListener(new OnClickListener(){  
		    @Override  
		    public void onClick(View v){  
		        MainActivity.this.openOptionsMenu();  //单击按钮弹出 OptionMenu
		    }  
		});           

10. Click a button to pop up (ContextMenu) context menu:

		//前提是:首先创建了 ContextMenu对象 ,然后做参数传入此方法
		this.openContextMenu(view)

14. Two display modes of Spinner: (dialog, drop-down list)

设置方式:
	    android:spinnerMode : 用来改变Spinner控件的显示样式,

				  两个属性值 :[比如:设置为弹出列表(dialog),下拉列表(dropdown)]
  1. In Android development, it is generally recommended to create projects that need to access the database:

    1.MySQLiteOpenHelper 类 ------用于创建数据库,与初始化表结构,更新表结构
    2.MyStudentDBDao 类   ------数据库操作类,用于做增删改查
    3.MyBaseAdapter 类 -------用于做数据展示时的数据适配器
    

16. Data refresh of AdapterView (such as: ListView) ----- When the content of the data source changes, the data of the Adapter should be refreshed

前提是:传给ListView(AdapterView)的list指向不能被改变,需要从始至终指向同一个内存,

General call: this.adapter.notifyDataSetChanged();

并且建议在 onStart 方法中调用 数据刷新方法

17. [There are ten common Dialogs]: ordinary Dialog, multi-button ordinary Dialog, ordinary list Dialog, single-selection list Dialog, multi-selection list Dialog, custom Dialog,

					    环形进度条Dialog,水平进度条Dialog	,以及:DatePickerDialog和TimePickerDialog		  

【详见】:...\笔记\android 开发\安卓开发—2\Dialog--对话框 文件夹 】

快速创建一个Dialog:因为此处可以使用链式方式编写代码 :

				new AlertDialog.Builder(MainActivity.this)
					.setMessage("哈哈哈哈")
					.setIcon(R.drawable.ic_launcher)
					.setTitle("我是普通对话框")
					.setPositiveButton("确定", new DialogInterface.OnClickListener() {
				
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.cancel(); //取消对话框
						}
					})
					.create().show();

  1. [Jump from MainActivity to target Activity and then return to MainActivity]

    【建议使用】: 销毁目标Activity的方式,让目标Activity出栈,由于MinaActivity没有被销毁毁,则会自动返回MainActivity
    
    【不建议直接】:从目标Activity用 显示意图(setClass(...))的方式,调回源Activity
    

19. At present, it is found that the common codes that can be written in the way of chain calls in Android are:

		AlertDialog 与 SharedPreferences ,Notification 


	例:new AlertDialog.Builder(MainActivity.this)
					.setMessage("哈哈哈哈")
					.setIcon(R.drawable.ic_launcher)
					.setTitle("我是普通对话框")

    例:this.sp.edit().putString("enableLogin_str", "true").commit();


    例://使用链式调用创建通知对象----3.0以上高版本的写法 
		    	Notification notif = new  Notification.Builder(this)
		    				.setContentTitle("我是大标题")
		    				.setContentText("我是通知内容")
		    				.setSmallIcon(R.drawable.ic_launcher)
		    				.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
		    				//.setContentIntent(pendingIntent) //[设置延期意图,可以实现单击通知栏打开其他的系统组件 ]
		    				.build();

    	【注意】:创建Notification对象的链式调用发送,只有在 Android3.0(API 11)以上的机器上才能使用。

    	 	如果想让自己的Notification兼容低版本手机:则可以这样写:	

    			//兼容低版本的写法  用过时的方法
				Notification noti = new Notification(R.drawable.ic_launcher, "接收到了一条通知", System.currentTimeMillis());
					
				//[发送通知 
				nm.notify(2, noti);

  1. 【Get the version number of the current program】

public static String getAppVersion(Context context) {
String version = “0”;
try {
version = context.getPackageManager().getPackageInfo(
context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return version;
}

————————————————————————————————————————————
21. new Date().toLocaleString() // Although it has been deprecated, it still works well

	效果如:2016年 10月 12日 01:51:44

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
_ 】:

	Color.parseColor("#ff4081")); //将16进制的颜色值解析成int 型的 Color值

例:button1.setBackgroundColor(Color.parseColor("#ff0000")); //将此Button 的颜色设置为 红色

————————————————————————————————————————————————————————————————

23. It is recommended to use the id field as the primary key (auto-increment) and the Integer type (actually: 32-bit int type) for tables in the SQLiteDataBase database

			【账号id用于修改,删除账号时做标识使用,数据展示时则根据账号在容器中的位置来决定】

		db.execSQL("create table account_Table(accID integer primary key autoincrement,accTitle varchar(50)");

获取主键的值:cursor.getInt();   

			accBean.setAccID(cursor.getInt((cursor.getColumnIndex("accID")))); //填充id 字段

id 做标识来删除记录:			

	db.execSQL("delete from  account_Table where accID=? and accTitle=? ",new Object[]{accBean.getAccID(),accBean.getAccTitle()});	

——————————————————————————————————————————————————————————————————————————————————
24.

1.获取ROM 的根路径:通过 Environment可以获取ROM的根路径 ---------//即:/data

					Environment.getDataDirectory().getPath();

2.获取应用程序的私有目录(包含在ROM中):

		有两种方式:1.context.getFileDir().getPath();		//获取私有目录的路径(data/data/packagename/files)
					2.context.openFileIn(Out)put(name,mode) //获取私有目录的输入输出流

	2.1:获取data/data/packagename/Cache目录的路径						

				context.getCacheDir().getPath();

3.获取SDCard的路径:通过 Environment可以获取sdcard的路径

	 			 Environment.getExternalStorageDirectory().getPath(); ------ :/storage/sdcard1 ------真正的SD卡的路径
																		 
	注意:操作SD卡必须注册权限:

	 					<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

25. Regarding the conversion of JavaBean and Json data, it is recommended to use the Gson framework provided by Google

1.首先在项目中导入 gsonxx.jar 包。


	【注意】:gson包导入成功后,编译项目时 bin\dexedLibs\目录下自动会将 gson.jar 包添加进来
			  因此导入成功后无需考虑程序在 用户手机上运行时 是否支持 gson 包
			

2.然后使用可以用:toJson()系列的方法 将 java对象转换成 json 数据
				  fromJson()系列的方法用于将JSON数据转换为相应的Java对象

—————————————————————————————————————————————

  1. There are two ways to implement the sharing function: 1. [Use the sharing interface that comes with the system: (a sharing list will be displayed for the user to choose)]

    									例: //【分享文字】
    									        Intent shareIntent = new Intent();
    									        shareIntent.setAction(Intent.ACTION_SEND);
    									        shareIntent.putExtra(Intent.EXTRA_TEXT, "This is my Share text.");
    									        shareIntent.setType("text/plain");
    									 
    									        //设置分享列表的标题,并且每次都显示分享列表
    									        startActivity(Intent.createChooser(shareIntent, "分享到"));
    									    
    					2.【使用第三方的 分享功能 sdk	】		
    

——————————————————————————————————————————————————————————————————————————————————————————

29. The use of the four major components requires registration in the manifest file, except for the broadcast receiver; because it can also be registered dynamically (and the ResultReceiver does not need to be registered).

And all four components can define IntentFilter.

And the creation of the four major components is: create a class and then inherit from a component class (for example: MainActivity extends Activity)
MyFristService extends Service
MyReceiver extends BroadcastReceiver
AccountProvider extends ContentProvider
————————————————— ———————————————————————————————————————————————————— ————————————————————————————
30. Shield the Back key:

	由于按下Back键后系统会调用:onBackPressed();方法,而该方法默认会调用父类的onBackPressed(),且父类的该方法内部就是 finish();

	因此将对父类该同名方法的调用代码 注释掉时候就可以实现back键的屏蔽了

		例:
			
			 @Override
		    public void onBackPressed() {
		      // super.onBackPressed();
		    }

  1. 设置当前线程睡眠可以用,Thread.sleep(...) ,或者Thread.currentThread().sleep(time) ,但是都会需要异常处理
    

    Android can use SystemClock.sleep(ms) to achieve sleep without exception handling,

    The difference between the two: Thread.sleep() is a function provided by java. InterruptedException may occur during calling this function.
    SystemClock.sleep() is a function provided by android. In the process of calling this function, no InterruptedException exception will occur, and the interrupt event will be delayed until the next interrupt event. u

———————————————————————————————————————————————————— ——————————
32. There are two ways to deal with the interface:
1. Create a class to implement the interface
2. View and use the subclass of the interface

The interface can hide the details of the code, allowing programmers to expose part of the code they want to expose


  1. Some interview questions about AIDL and IPC:

    AIDL(Android接口定义语言) 可以用于实现 IPC(跨进程通信)
    

——————————————————————————————————————————————————————————————————————

34. [There are many ways to realize cross-process communication in Android:

	其中有4种方式正好对应于android系统中4种应用程序组件[Activity、Service、Broadcast 和ContentProvider--ContentResolver]】:


1.其中Activity可以跨进程调用其他应用程序的Activity   --------------------------【使用隐式意图】

2.Service和Content Provider类似,也可以访问其他应用程序中的数据,(但ContentProvider返回的是Cursor对象,而Service返回的是Java对象)
													 --------------------------【AIDL】	

3.Broadcast可以向android系统中所有应用程序发送广播(有序广播可以携带数据),而需要跨进程通讯的应用程序可以监听这些广播;
													----------------------------【BroadcastReceiver】					

4.ContentResolver可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操作;

													  --------------------------【Cursor】

———————————————————————————————————————————————————— ——————————————
35. After obtaining the Cursor object, you must make advanced judgments and use the cursor if the conditions are met:

	if(cursor!=null &&!cursor.isClosed() && cursor.getCount()>0){ //游标对象不为空,且结果集没有关闭,且查询到的数据不为空
		
		....

		//使用完记得资源清理
		cursor.close();
		db.close();
	}
  1. How to turn an Android project into a class library file?

    在项目上 右键-->Properties-->Android--》勾选 is Library 就可以吧自己的项目标志成一个 类库。---但标志后就不可以部署运行了		
    
    同理 取消勾选 is Library 就可以将一个 类库文件变回原来的 安卓项目文件----就可以部署运行了
    

37. [Note: When receiving a new project, first open eclipse–”window–>Preferences–”workspace—> it is recommended to change the encoding to UTF-8]
——————————————— —————————————————————————————————————————— 38.
The difference and use of versionName and versionCode:

		versionCode :版本号 ,用于与服务端的版本号进行比较,看是否需要更新应用。
		versionName : 版本名称,用于提示给用户,如 :1.0.0 ,最后一位代表修复原有版本的bug
															 倒数第二位代表更新了部分功能
															 第一位代表项目重大更新,例:代码重构,界面变化,大部分功能添加

———————————————————————————————————————————————————— —————
39.【What is the difference between the four values ​​of minSdkVersion, maxSdkVersion, targetSdkVersion, and Compile With?】

> minSdkVersion, maxSdkVersion 是项目支持的最低sdk版本和最高sdk版本. 在安装apk前,系统会对这个两值进行判断, 决定当前系统是否可以安装。								且一般maxSdkVersion不会设置

>targetSdkVersion:会告诉系统,此版本已经经过充分测试,那么程序运行在该版本的系统时,就不会做过多额外的兼容性判断.运行效率会高一些。

> Compile With 是项目编译时的sdk版本:一般都选择较高的编译版本

[Supplement: The minimum and target versions will be marked in the manifest file, and the compiled version will be written in the project.properties file]

—————————————
40. In Eclipse: Select the method name or class name and use the shortcut key: alt+shift+J to achieve quick documentation comments.
In Eclipse: In the entity class: alt+shift+s After the pop-up window, press s to enter the geter/seter method setting window.
In Eclipse: If you need to automatically generate the toString() method: right-click – "source – "generate toString.
—————————————————————————————————————————
41. [Version detection during the learning process, app download update and other functions:]

本程序为了简便则直接在本机的 Tomcat根目录/webapps/ROOT/目录下放置文件然后直接访问即可。

		例:首先将Json字符串保存成一个文本文件(mobileSafe_Update02.json),然后存储到Tomcat根目录/webapps/ROOT/目录下
			开启TomcatServer后:用浏览器直接访问 http://localhost:8080/mobileSafe_Update02.json 即可看到json文本。

		例2:同理直接将mobilesafe1.0.1.apk放置到 Tomcat根目录/webapps/ROOT/目录下。
			开启TomcatServer后:用浏览器直接访问 http://localhost:8080/mobilesafe1.0.1.apk 即可弹窗提示下载apk文件。

	【但是实际开发中,用手机访问网络因此不能使用电脑的localhost。】

		解决方式:

			1.购买服务器,注册域名然后获得一个公网的ip,再用手机访问
			2.使用开启了Tomcat服务的电脑的IP地址(内网ip)。---前提是手机与电脑在同一个局域网下
			3.或者在自己的电脑上使用工具将ip映射到公网上。---例如:花生壳等工具即可实现。

			4.【Google提供了解决方案:直接在模拟器使用10.0.2.2就可以访问到电脑上的Tomcat服务器 】---【推荐使用】			

				例:开启Tomcat后,在模拟器的浏览器上输入:http://10.0.0.2:8080/mobilesafe1.0.1.apk 即可提示下载apk

42. In Android development, you should try to use Log.xxx to print the log to debug the program. Instead use System.out.pritnln();

In eclipse: ctrl + shift + x: convert the selected letter to uppercase, ctrl+shift+y: lowercase.

43. Tip: You can also use the Handler–Message mechanism to remind the user of the abnormal situation in the program;
try{ }catch (MalformedURLException e) { e.printStackTrace(); //Tip: You can also use Handler–Message Mechanism to realize the abnormal situation that prompts the user program msg.what = URL_ERROR;




		} catch (IOException e) {
			e.printStackTrace();
			msg.what = IO_ERROR;
		}
		finally{
			handler.sendMessage(msg);
		}
小技巧:可以自行封装一些Utils类 例如:ToastUtils.java		
  1. Tip: Select the custom TextView class name and right-click – "copy Qualified name --> to get the full class name of the class. com.xx.xxx
    This method can be applied to the class name of any class to obtain the full name of the class.

45. Sometimes a method is overridden and the parameters of the discovery method are represented by arg0, arg1... This means that this class has no associated source code.

解决方案:添加源码关联即可。

46.handler.sendEmptyMessageDelayed(ENTER_HOME, 4000); //Send a message, let him delay for 4 seconds before processing.

47. You can create a special class (MyConstantValues) to save and manage the constants needed in the project. When using: MyConstantValues.XXX.

48. In actual development, you can subcontract according to the components. For example: com.hzy.xxx.activity,com.hzy.xxx.service…

49. In the layout file, after the parent control tag, you can use android:padding="10dp" to set the padding to 10dp.
, You can also set android:layout_margin="10dp" in the child control to set the inner margin to 10dp.


50. Access the files under the assets resource directory in the project.

例://[1]:首先获取assets资产目录管理器
	AssetManager assetManager = getAssets();

	//[2]:然后获取assets 资产目录下指定文件的输入流
	InputStream inputStream=null;
	try {
		inputStream = assetManager.open(dbName);
	} catch (Exception e1) { e1.printStackTrace();
	}

———————————————————————————————————————————————————— ———————————————————————————
51. [Search keywords from a project in the entire Eclipse. 】----Decompilation is commonly used

 选中整个项目--》ctrl + h ,即可全项目搜索某一个字符串了。

【查看一个类的继承结构】

	选中一个类 :ctrl+T 即可查看	

52.【Use the vibrator to realize the vibration effect of the mobile phone】

		//获取震动器对象
		Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		//开始震动。需要注册震动权限<uses-permission android:name="android.permissionsion.VIBRATE"/>
		vibrator.vibrate(1000);
		//规律震动,(暂停时间,震动时间,暂停时间,震动时间) ,重复次数
		//vibrator.vibrate(new long[]{2000,1000,2000,1000}, 2);
		//取消震动
		vibrator.cancel();

52. Although Toast can also pop up in Service, getApplicationContext() must be used; remember not to use this.

	Toast.makeText(getApplicationContext(), "来电显示服务已经关闭!", 0).show(); 			
  1. [Implementation of transparent Activity. You only need to set the theme attribute value for this Activity tag in the manifest file:]

    例:Activity背景全透明:
      	  <activity 
            android:name=".activity.SetToastLocationActivity"
          	android:theme="@android:style/Theme.Translucent.NoTitleBar"
            >
    

    [If a translucent effect is required, you can set the background property of the underlying layout to a translucent color value (for example: #acfc) in the layout file of this Activity.]

54. There are two ways to change the coordinates of a control:

	例:1.view.setX() , view.setY();  //左上角点坐标
		2.view.layout(int l, int t, int r, int b) //左,上,右,下。四个顶点的坐标。

55.【Two consecutive click events can be used as double-click events. Implement the double-click event monitoring of the control. Generally, the time interval is set within 500 milliseconds.

	query_number_address_Btn.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {

				if(System.currentTimeMillis()-firstClickTime<500){
				//双击实现 toast_imgview居中
				toast_imgview.setX(screen_width/2-toast_imgview.getWidth()/2);
				toast_imgview.setY(screen_height/2-toast_imgview.getHeight()/2);
				
				}else{
					//单击,则记录第一次点击的时间
					firstClickTime=System.currentTimeMillis();
				}
			}
		};
  1. ★【If the self-increasing id is used as the primary key, the child thread must be restarted to obtain data and refresh the adapter.

         并且由于数据库中记录的id,不会自动刷新,例如:id为11的记录被删除了,则id为12的记录id仍然为12。因此11这个id就没有记录了。
    
         且在beans集合中对象是从0开始排列的,而数据库中 自增的id字段则是从1开始排列的。
    
         】
    

[When deleting or updating data records in the database:

  强烈建议使用 id字段与其他字段结合做删除条件。否则如果只用 phonenumber做删除条件。

  因为一旦数据库中有相同的phonenumber,则在删除数据时会出现 bug .

  1. [Add a local refresh method to synchronize the additions, deletions, and changes to the local beans every time the addition, deletion, and modification of the database are completed. Then enable local data refresh. Instead of requesting the next page.

58.- The installation location of this application can be specified in the manifest file

		manifest根标签具有这样的属性,用来指定apk的安装位置, 缺省值是手机内存 android:installLocation="auto", 可以修改为auto, 表示优先使用手机内存, 如果内存不够,再使用sdcard. 不建议强制安装在sdcard,因为某些手机没有sdcard,会导致安装失败.设置完成后,就可以在系统应用管理中,移动apk的安装位置了.

59. [Let ImageButton realize the simple display of pictures like ImageView without background (ie: transparent background).

【只需将 ImageButton的background属性设置为 android:background="@null"  然后用  android:src属性设置需要展示的图片即可。】

60. Since ViewPager belongs to android.support.v4.view.ViewPager, if you want to see the source code, you must follow the steps below:

	[1]:找到项目中libs下 android-support-v4.jar --右键--》Add To Build Path

	[2]:然后在 Referenced Libraries中 找到  android-support-v4.jar 中的 android.support.v4.view.ViewPager类。

	[3]:此时就可以点开 ViewPager.class ,然后可以 Attach Source ,选择 /sdk/extras/android/support/v4/src 即可看到源码。

61. Since TextView does not have a click event by default, there are two ways to set a click event for TextView:

1.在java代码中为TextView设置单击事件监听

2.在布局中为TextView设置 onClick属性值为一个方法名。----前提是需要先设置 onClickable="true" 才行。

62. When multiple controls have some common attribute values:

可以首先编写好一个控件的布局代码,然后在该标签中 ctrl+1 选择 Extract style ,就可以快速的抽取成 style标签。	

使用这个小技巧,可以避免手动复制粘贴 布局代码到 style.xml文件中。

63. Solve the problem that the emulator cannot input Chinese (no matter whether it is a soft keyboard or a physical keyboard):

解决方案:进入模拟器  Setting --》Language&Input -- 》Language --》选择简体中文 ---》键盘选择 谷歌拼音

			 --》然后在任意EditText中点击--》选择键盘 谷歌拼音,此时就可以输入中文了。

64: [There are four ways to realize the sidebar (side sliding panel) effect]:

	△创建一个自定义控件 SlideMenuPanelLLayout 继承自ViewGroup。(继承ViewGroup则必须实现抽象方法onLayout())

	★[其实也可以使用系统自带的 :android.support.v4.widget.SlidingPaneLayout ,它也是继承自ViewGroup的]

	△[也可以使用第三方开源的自定义控件:例如:SlidingMenu]

	▲【推荐使用Google官方推出的 DrawerLayout ,结合 Navigationview 】

65.: [View files in the data/data/ directory of the application without root]

	在AnroidManifest.xml中将 application节点下的 android:debuggable 属性设置为true; 否则,将无法在没有root权限的情况下查看应用的目录,会得到类似 permission denied的信息。

66. When the application enters the background and the memory is insufficient, the system will recycle the Activity. Usually we all know to use OnSaveInstanceState() to save the state, and use OnRestoreInstanceState() to restore the state.

67. [It is recommended to provide a getAppContext() method in the custom BaseApplication. You can use this to pop up Toast in the future.

public class BaseApplication extends Application {
	
	private static BaseApplication mContext = null;

	@Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
    }

	public static Context getAppContext() {
        return mContext;
    }
}

【注意】:使用Application提供的Context固然方便,但是有些时候不能使用Application的Context,不然会报错(比如startActivity(),显示Dialog等)。

【附】:调用 getResource() 方法时也建议使用Application的上下文。即:BaseApplication.getAppContext().getResources();;
在处理异常方面,UncaughtExceptionHandler可以对全局的异常进行捕获。测试崩溃可以使用Testin apm或bugly一些平台。

在Android中引用四大组件和Fragment这些重量级对象的时候要用WeakReference,常用的场景是static Handler持有Activity。

能用简单的布局就用简单的,特别是FrameLayout,它的layout_gravity属性非常好用。

BuildConfig.Debug可以判断是不是debug版本,可以通过它来控制一些调试代码,比如debug版本下打日志和测试服务器,release下不打日志,用正式服务器。

View可以getContext(),所以在设计方法的时候,参数中如果有View了就别搞Context这个参数了。View还可以post(),有view的时候就别new Handler().post()了。在给Handler发送消息的时候没必要每次都new Message(),而是使用handler.obtainMessage(),它会先看看消息队列里面有没有没用的消息,如果有可以复用消息对象。

如果是在应用范围内的广播可以使用LocalBroadcastManager这个API(低版本用v4下的),更加安全高效,不必担心别的app伪造广播或收听你的广播做一些不好的事情。

可以找一找你常用的app里面的开源许可,里面可以看到使用了哪些具体的开源项目。android开发一般都使用什么框架? - gzw1993 的回答最后,

善用Google和StackOverFlow,比百度和CSDN靠谱多了,比如想查下如何从代码中设置TextView的drawLeft属性,google搜索“android textview drawableLeft programmatically”即可,这是搜索到的第一条里面的内容:
  1. android:animateLayoutChanges This is a very cool property.

    After adding android:animateLayoutChanges="true" to the parent layout, if the layout method is triggered (for example, its child View is set to GONE), the system will automatically add animation effects when the layout changes for you! !

  2. The tools tag can help developers preview the effect of xml in real time.
    The controls occupied by the control can be previewed through tools:background, and
    tools:visibility can display a gone control when previewing, and the content of the tools tag after running will not be displayed.

For example:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:background="#FF00FF"
    tools:visibility="visible"
    tools:text="这段话只在预览时能看到,运行以后就看不到了" />
  1. getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE) Set the security window and disable the system screenshot.

    Prevent some interfaces in the app from being screenshotted and displayed on other devices to cause information leakage. (The common way to take a screenshot of the mobile phone device system is to press the power button and the volume button at the same time.)

  2. In the onCreateViewHolder() method of RecycleViewAdapter, you can use:

    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());

    To get the layoutInflater, so as not to let the Adapter hold the Activity.

  3. Determine which Context to use: The easiest way is to decide what parameters to pass according to the life cycle of the control (or component).

  4. Application can be used to transfer data between components of a single process.

    Usually, in order to transfer objects between two components, we need to realize the Parcellable or Serializable interface of the object. But if the two Activities are in the same process, then it can be implemented with Application.

  5. When we call the getSharedPreference() method, the SharedPreference data in the disk file will actually be loaded into memory.

    Therefore, when we access a data stored in SharedPreference, it will actually be obtained from the memory cache, so there is no need to worry about efficiency.

    However, you need to pay attention when writing data to SharedPreference: in most cases, we use apply is enough, because apply() is written to memory synchronously, and then submitted to disk asynchronously, while commit() is written synchronously to memory and written to disk synchronously.

  6. To judge whether the current thread is the main thread in the Java program, you can use the method of printing the Thread Name to distinguish the main thread, but there is a simpler method in the Android program.

    boolean isMainThread = (Looper.myLooper() == Looper.getMainLooper());
    

    Can be encapsulated into a tool method:

    public void checkWorkerThread() {
        boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
        if (isMainThread) {
            if (BuildConfig.DEBUG) {
                throw new RuntimeException("Do not do time-consuming work in the Main thread");
            }
        }
    }
    
  7. Determine whether the current program is running in the main process

    // Determine whether the current code is running in the main process, if so, return true
    private boolean isMainProcess() { ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)); List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses() ; String mainProcessName = getPackageName(); int myPid = Process.myPid(); // Get the current process id for (ActivityManager.RunningAppProcessInfo info : processInfos) { if (info.pid == myPid && mainProcessName.equals(info.processName) ) { return true; } } return false; }










  8. Difference Between Jar and Aar

Jar包里面只有代码,aar里面不光有代码还包括代码还包括资源文件,比如 drawable 文件,xml 资源文件。对于一些不常变动的 Android Library,我们可以直接引用 aar,加快编译速度
  1. Use reflection to start Activity based on ActivityName

    Class c = Class.forName(ACTIVITY_NAME_TEMPLATE + Main + “Activity”);
    Intent intent = new Intent(mActivityWeakRef.get().getApplicationContext(), c);
    startActivity(intent);

  2. Use Gson to implement deserialization, and when json is passed and parsed into a Bean object, if a member defined in the class of the Bean object is of String type, it can be compatible with any common data type in the json data.

    例:
    TestBean{
    public String textSize;
    }

    json
    
    {
     "textSize":14
    }
    

    At this point it is still possible to inject 14 into the TestBean.textSize field. (The final result is: textSize content is "14")

    In the same way, it can also be injected into a Map<String, String>:

    例: 除了List<Map<String,Object>> , List<Map<String,String>>  也能容纳任何数据类型的json 属性值。
    
    	List<Map<String,String>> mapList = GsonUtil.fromJson(Base64Util.decrypt(newMenusData),new TypeToken<List<Map<String,String>>>(){}.getType());
    
  3. [Through the package name, you can actually open all the apps on the phone]

  • If you just open these programs, you can use the desktop icon to start, just use the [package name] to open any application on the desktop!

Note: Before opening, it is necessary to determine whether the application corresponding to the specified package name exists

	//例: 利用包名打开支付宝
	PackageManager packageManager = this.getApplicationContext().getPackageManager();
	Intent intent = packageManager.getLaunchIntentForPackage("com.eg.android.AlipayGphone");
	startActivity(intent);

For more details, see: …\android development\Intent\Implicit intent and explicit intent.txt

Guess you like

Origin blog.csdn.net/UserFrank/article/details/129206434