Desarrollo de Android - Resumen de consejos 2

  1. Al iniciar la máquina virtual, hay un borrado de datos de usuario en la ventana de opciones de inicio. Al marcarlo, la máquina virtual [restaurará la configuración de fábrica]

2. [Si desea que su aplicación tenga varios íconos de inicio:]

为一个应用的 多个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. -------- Intención implícita ---------

    [marcador de teléfono abierto]

     /*  -------简写-------	
         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.---------Intención de visualización---------

[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); //Usar el conjunto de caracteres especificado (método de codificación), codificar la cadena en una matriz de bytes y devolver

6.----------------------------------【Actividad dos métodos de inicio, cuatro modos de inicio】- --- ---------------------------------------------------------
【Actividad dos métodos de inicio】 :

	普通方式:startActivity(intent);

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

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

[Los cuatro modos de inicio de la actividad]:

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

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

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

7. Una actividad normal en ejecución cambia repentinamente a una pantalla horizontal o vertical: [se destruirá primero y luego se creará] onPause–>onStop–>onDestroy–>onCreate–>onStart–>onResume

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

8. El uso de la etiqueta de inclusión en el archivo de diseño xml puede hacer referencia a otros archivos de diseño en la posición especificada de este archivo de diseño:

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

-------------------------[Haga clic en un botón para que aparezcan varias formas de menús] – OptionMenu, ContextMenu, PopupMenu ------ - --------------------------

9. Haga clic en un botón en Android para que aparezca optionMenu (menú de opciones). Simplemente llame al método Activity.this.openOptionsMenu();

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

10. Haga clic en un botón para abrir el menú contextual (ContextMenu):

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

14. Dos modos de visualización de Spinner: (diálogo, lista desplegable)

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

				  两个属性值 :[比如:设置为弹出列表(dialog),下拉列表(dropdown)]
  1. En el desarrollo de Android, generalmente se recomienda crear proyectos que necesiten acceder a la base de datos:

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

16. Actualización de datos de AdapterView (como: ListView) ----- Cuando cambia el contenido de la fuente de datos, los datos del adaptador deben actualizarse

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

Llamada general: this.adapter.notifyDataSetChanged();

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

17. [Hay diez diálogos comunes]: diálogo ordinario, diálogo ordinario de varios botones, diálogo de lista ordinaria, diálogo de lista de selección única, diálogo de lista de selección múltiple, diálogo personalizado,

					    环形进度条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. [Saltar de MainActivity a la actividad de destino y luego volver a MainActivity]

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

19. En la actualidad, se encuentra que los códigos comunes que se pueden escribir en forma de cadena de llamadas en Android son:

		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. 【Obtener el número de versión del programa actual】

public static String getAppVersion(Context context) { String versión = “0”; intente { versión = context.getPackageManager().getPackageInfo( context.getPackageName(), 0).versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } versión de retorno; }








21.
nueva fecha() .toLocaleString() // Aunque ha quedado en desuso, todavía funciona bien

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

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

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

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

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

23. Se recomienda utilizar el campo id como clave principal (incremento automático) y el tipo Integer (en realidad: tipo int de 32 bits) para tablas en la base de datos SQLiteDataBase

			【账号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. En cuanto a la conversión de datos JavaBean y Json, se recomienda utilizar el marco Gson proporcionado por Google

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


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

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

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

  1. Hay dos formas de implementar la función de uso compartido: 1. [Utilice la interfaz de uso compartido que viene con el sistema: (se mostrará una lista de uso compartido para que el usuario elija)]

    									例: //【分享文字】
    									        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. El uso de los cuatro componentes principales requiere el registro en el archivo de manifiesto, a excepción del receptor de transmisión, porque también se puede registrar dinámicamente (y no es necesario registrar el ResultReceiver).

Y los cuatro componentes pueden definir IntentFilter.

Y la creación de los cuatro componentes principales es: crear una clase y luego heredar de una clase de componente (por ejemplo: MainActivity extiende Actividad)
MyFristService extiende Servicio
MyReceiver extiende BroadcastReceiver
AccountProvider extiende ContentProvider
————————————— ———— ——————————————————————————————————————————————— —————— —————————————————————————————
30. Proteger la tecla Atrás:

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

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

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

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

    Android puede usar SystemClock.sleep(ms) para dormir sin manejo de excepciones,

    La diferencia entre los dos: Thread.sleep() es una función proporcionada por java. InterruptedException puede ocurrir durante la llamada a esta función.
    SystemClock.sleep() es una función proporcionada por android. En el proceso de llamar a esta función, no se producirá ninguna excepción InterruptedException y el evento de interrupción se retrasará hasta el próximo evento de interrupción. tu

———————————————————————————————————————————————————— —— ——————————
32. Hay dos formas de manejar la interfaz:
1. Crear una clase para implementar la interfaz
2. Ver y usar la subclase de la interfaz

La interfaz puede ocultar los detalles del código, lo que permite a los programadores exponer parte del código que quieren exponer.


  1. Algunas preguntas de la entrevista sobre AIDL e IPC:

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

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

34. [Hay muchas formas de realizar la comunicación entre procesos en 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. Después de obtener el objeto Cursor, debe hacer juicios avanzados y usar el cursor si se cumplen las condiciones:

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

		//使用完记得资源清理
		cursor.close();
		db.close();
	}
  1. ¿Cómo convertir un proyecto de Android en un archivo de biblioteca de clases?

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

37. [Nota: Al recibir un nuevo proyecto, primero abra eclipse–”ventana–>Preferencias–”espacio de trabajo—> se recomienda cambiar la codificación a UTF-8]
————————————— —— ——————————————————————————————————————————— 38.
La diferencia y el uso de versionName y versionCode:

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

———————————————————————————————————————————————————— —— —————
39.【¿Cuál es la diferencia entre los cuatro valores de minSdkVersion, maxSdkVersion, targetSdkVersion y Compile With?】

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

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

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

[Suplemento: las versiones mínima y objetivo se marcarán en el archivo de manifiesto, y la versión compilada se escribirá en el archivo project.properties]

—————————————
40. En Eclipse: seleccione el nombre del método o el nombre de la clase y use la tecla de método abreviado: alt+shift+J para obtener comentarios rápidos de la documentación.
En Eclipse: En la clase de entidad: alt+shift+s Después de la ventana emergente, presione s para ingresar a la ventana de configuración del método geter/seter.
En Eclipse: si necesita generar automáticamente el método toString(): haga clic con el botón derecho en "fuente" y genere toString.
———————————————————————————————————————————
41. [Detección de versión durante el proceso de aprendizaje , actualización de descarga de aplicaciones y otras funciones:]

本程序为了简便则直接在本机的 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. En el desarrollo de Android, debe intentar usar Log.xxx para imprimir el registro para depurar el programa. En su lugar, utilice System.out.pritnln();

En eclipse: ctrl + shift + x: convertir la letra seleccionada a mayúsculas, ctrl+shift+y: minúsculas.

43. Sugerencia: también puede usar el mecanismo Handler–Message para recordarle al usuario la situación anormal en el programa,
pruebe{ }catch (MalformedURLException e) { e.printStackTrace(); //Sugerencia: también puede usar Handler –Mecanismo de mensaje para darse cuenta de la situación anormal que solicita al programa de usuario msg.what = URL_ERROR;




		} catch (IOException e) {
			e.printStackTrace();
			msg.what = IO_ERROR;
		}
		finally{
			handler.sendMessage(msg);
		}
小技巧:可以自行封装一些Utils类 例如:ToastUtils.java		
  1. Sugerencia: seleccione el nombre de clase de TextView personalizado y haga clic con el botón derecho en "copiar nombre calificado --> para obtener el nombre de clase completo de la clase. com.xx.xxx
    Este método se puede aplicar al nombre de clase de cualquier clase para obtener el nombre completo de la clase.

45. A veces se anula un método y los parámetros del método de descubrimiento se representan mediante arg0, arg1... Esto significa que esta clase no tiene código fuente asociado.

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

46.handler.sendEmptyMessageDelayed(ENTER_HOME, 4000); //Envía un mensaje, deja que se demore 4 segundos antes de procesar.

47. Puede crear una clase especial (MyConstantValues) para guardar y administrar las constantes necesarias en el proyecto.Al usar: MyConstantValues.XXX.

48. En el desarrollo real, puede subcontratar según los componentes. Por ejemplo: com.hzy.xxx.actividad,com.hzy.xxx.servicio…

49. En el archivo de diseño, después de la etiqueta de control principal, puede usar android:padding="10dp" para establecer el relleno en 10dp.
, También puede establecer android:layout_margin="10dp" en el control secundario para establecer el margen interior en 10dp.


50. Acceda a los archivos bajo el directorio de recursos de activos en el proyecto.

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

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

———————————————————————————————————————————————————— —— ————————————————————————————
51. [Buscar palabras clave de un proyecto en todo el Eclipse. 】----La descompilación se usa comúnmente

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

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

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

52.【Use el vibrador para darse cuenta del efecto de vibración del teléfono móvil】

		//获取震动器对象
		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. Aunque Toast también puede aparecer en Service, se debe usar getApplicationContext(), recuerde no usar esto.

	Toast.makeText(getApplicationContext(), "来电显示服务已经关闭!", 0).show(); 			
  1. [Implementación de actividad transparente. Solo necesita establecer el valor del atributo de tema para esta etiqueta de actividad en el archivo de manifiesto:]

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

    [Si se requiere un efecto translúcido, puede establecer la propiedad de fondo del diseño subyacente en un valor de color translúcido (por ejemplo: #acfc) en el archivo de diseño de esta Actividad.]

54. Hay dos formas de cambiar las coordenadas de un control:

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

55.【Se pueden usar dos eventos de clic consecutivos como eventos de doble clic. Implemente el monitoreo de eventos de doble clic del control. Generalmente, el intervalo de tiempo se establece en 500 milisegundos.

	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. ★【Si la identificación de aumento automático se usa como clave principal, el subproceso secundario debe reiniciarse para obtener datos y actualizar el adaptador.

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

[Al eliminar o actualizar registros de datos en la base de datos:

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

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

  1. [Agregue un método de actualización local para sincronizar las adiciones, eliminaciones y cambios en los beans locales cada vez que se complete la adición, eliminación y modificación de la base de datos. Luego habilite la actualización de datos locales. En lugar de solicitar la página siguiente.

58.- La ubicación de instalación de esta aplicación se puede especificar en el archivo de manifiesto

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

59. [Deje que ImageButton realice la visualización simple de imágenes como ImageView sin fondo (es decir, fondo transparente).

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

60. Dado que ViewPager pertenece a android.support.v4.view.ViewPager, si desea ver el código fuente, debe seguir los pasos a continuación:

	[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. Dado que TextView no tiene un evento de clic de forma predeterminada, hay dos formas de configurar un evento de clic para TextView:

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

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

62. Cuando múltiples controles tienen algunos valores de atributos comunes:

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

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

63. Resuelva el problema de que el emulador no puede ingresar chino (no importa si es un teclado virtual o un teclado físico):

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

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

64: [Hay cuatro formas de realizar el efecto de barra lateral (panel deslizante lateral)]:

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

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

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

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

65.: [Ver archivos en el directorio data/data/ de la aplicación sin root]

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

66. Cuando la aplicación entre en segundo plano y la memoria sea insuficiente, el sistema reciclará la Actividad. Por lo general, todos sabemos usar OnSaveInstanceState() para guardar el estado y usar OnRestoreInstanceState() para restaurar el estado.

67. [Se recomienda proporcionar un método getAppContext() en el BaseApplication personalizado. Puede usar esto para abrir Toast en el futuro.

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 Este es un atributo muy bueno.

    Después de agregar android:animateLayoutChanges="true" al diseño principal, si se activa el método de diseño (por ejemplo, su Vista secundaria está configurada como GONE), el sistema agregará automáticamente efectos de animación cuando el diseño cambie para usted. !

  2. La etiqueta de herramientas puede ayudar a los desarrolladores a obtener una vista previa del efecto de xml en tiempo real.
    Los controles ocupados por el control se pueden previsualizar a través de herramientas:fondo y
    herramientas:visibilidad puede mostrar un control desaparecido durante la vista previa y el contenido de la etiqueta de herramientas después de ejecutarse. no se mostrará.

Por ejemplo:

<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) Configure la ventana de seguridad y deshabilite la captura de pantalla del sistema.

    Evite que algunas interfaces de la aplicación se capturen y se muestren en otros dispositivos para provocar la fuga de información. (La forma común de tomar una captura de pantalla del sistema del dispositivo del teléfono móvil es presionar el botón de encendido y el botón de volumen al mismo tiempo).

  2. En el método onCreateViewHolder() de RecycleViewAdapter, puede usar:

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

    Para obtener el layoutInflater, para no permitir que el adaptador retenga la actividad.

  3. Determine qué contexto usar: la forma más fácil es decidir qué parámetros pasar de acuerdo con el ciclo de vida del control (o componente).

  4. La aplicación se puede utilizar para transferir datos entre componentes de un solo proceso.

    Por lo general, para transferir objetos entre dos componentes, necesitamos realizar la interfaz Parcelable o Serializable del objeto. Pero si las dos actividades están en el mismo proceso, entonces se puede implementar con la aplicación.

  5. Cuando llamamos al método getSharedPreference(), los datos de SharedPreference en el archivo del disco se cargarán en la memoria.

    Por tanto, cuando accedamos a un dato almacenado en SharedPreference, en realidad se obtendrá de la memoria caché, por lo que no hay que preocuparse por la eficiencia.

    Sin embargo, debe prestar atención al escribir datos en SharedPreference: en la mayoría de los casos, usamos apply es suficiente, porque apply() se escribe en la memoria de forma síncrona y luego se envía al disco de forma asíncrona, mientras que commit() se escribe de forma síncrona en la memoria y escrito en el disco sincrónicamente.

  6. Para juzgar si el hilo actual es el hilo principal en el programa Java, puede usar el método de imprimir el Nombre del hilo para distinguir el hilo principal, pero hay un método más simple en el programa Android.

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

    Se puede encapsular en un método de herramienta:

    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. Determinar si el programa actual se está ejecutando en el proceso principal

    // Determine si el código actual se está ejecutando en el proceso principal, de ser así, devuelva true
    private boolean isMainProcess() { ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)); List<ActivityManager.RunningAppProcessInfo> processInfos = am. getRunningAppProcesses() ; String mainProcessName = getPackageName(); int myPid = Process.myPid(); // Obtener el ID del proceso actual para (ActivityManager.RunningAppProcessInfo info : processInfos) { if (info.pid == myPid && mainProcessName.equals( info.processName) ) { devuelve verdadero; } } devuelve falso; }










  8. Diferencia entre Jar y Aar

Jar包里面只有代码,aar里面不光有代码还包括代码还包括资源文件,比如 drawable 文件,xml 资源文件。对于一些不常变动的 Android Library,我们可以直接引用 aar,加快编译速度
  1. Use la reflexión para iniciar la actividad basada en ActivityName

    Clase c = Class.forName(ACTIVITY_NAME_TEMPLATE + Main + “Activity”);
    Intención intención = nueva intención (mActivityWeakRef.get().getApplicationContext(), c);
    iniciarActividad(intención);

  2. Use Gson para implementar la deserialización, y cuando se pasa json y se analiza en un objeto Bean, si un miembro definido en la clase del objeto Bean es de tipo String, puede ser compatible con cualquier tipo de datos común en los datos json.

    Ejemplo:
    TestBean{ public String textSize; }

    json
    
    {
     "textSize":14
    }
    

    En este punto, todavía es posible inyectar 14 en el campo TestBean.textSize. (El resultado final es: el contenido del tamaño del texto es "14")

    De la misma forma, también se puede inyectar en un 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. [A través del nombre del paquete, puede abrir todas las aplicaciones en el teléfono]

  • Si solo abre estos programas, puede usar el ícono del escritorio para comenzar, ¡simplemente use el [nombre del paquete] para abrir cualquier aplicación en el escritorio!

Nota: antes de abrir, es necesario determinar si existe la aplicación correspondiente al nombre del paquete especificado

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

Para obtener más detalles, consulte: …\desarrollo de Android\Intent\Intent implícito e intento explícito.txt

Supongo que te gusta

Origin blog.csdn.net/UserFrank/article/details/129206434
Recomendado
Clasificación