Android基础知识点学习总结
Posted 呓夏v
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android基础知识点学习总结相关的知识,希望对你有一定的参考价值。
android基础知识点学习总结
安卓基础知识个人学习笔记分享~
一、Android系统架构
Linux内核层→系统运行层→应用框架层→应用层
1、Linux内核层:Android系统是基于Linux内核的,这一层为硬件提供了底层的驱动,例如显示驱动,音频驱动,电源管理等等
2、系统运行库层:这一层主要通过C/C++实现,为Android系统提供支持,例如SQLite库提供了数据库的支持,Webkit提供了浏览器内核的支持(SQLite数据库:轻量级,嵌入式关系型数据库)
3、应用框架层:这一层提供了应用程序可能用到的各种API,我们开发者可以使用这些API来构建自己的应用程序
4、应用层:所有安装在手机上的应用程序都是属于这一层,当然也包括我们自己开发的应用程序
二、四大组件
Activity→Service→BroadcastReceiver→ContentProvider
1、Activity:所有看的到东西都是放在Activity中的
2、Service:我们无法看见他,他只会在后台默默运行,即使我们退出了应用,也是可以继续运行的
3、BroadcastReceiver:他允许应用接收来自各处的广播消息,例如电话,短信等,我们开发的程序也可以通过他向外发出广播消息
4、ContentProvider:为应用程序之间共享数据提供了可能,例如读取系统通讯录中的联系人,我们可以使用他来实现
三、目录结构各文件含义
.gradle和.idea
放置的都是Android Studio自动生成的一些文件
gradlew和gradle.bat
这两个文件是用来在命令行界面中执行gradle命令的,其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows中使用的
HelloWorld.iml
这个文件是IntelliJ IDEA自动生成的(Android Studio是基于IntelliJ IDEA的),用于标识这是一个IntelliJ IDEA项目
local.properties
用于指定本机中的Android SDK路径,通常是自动生成的,如果SDK位置改变了,我们需要将文件中的路径改成新的位置即可。
setting.gradle
用于指定项目中所有引入的模块,通常都会自动完成
app目录下
libs目录
如果我们使用了第三方jar包,就需要将这些jar包都放在这个目录下,然后他会自动添加到项目的构建路径里
AndroidManifest.xml
这是整个Android项目的配置文件,我们在程序中定义的四大组件都需要在这个文件里注册,还可以在这个文件中给应用程序添加权限声明。****没有在这个文件中注册的组件是不能使用的!****MainActivity是我们编写的门面,然后将这个MainActivity注册进AndroidManifest.xml中才可以使用。
android.intent.action.MAIN决定应用程序最先启动的Activity ,android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里。Main和LAUNCHER同时设定才有意义。
Proguard-rules.pro
用于指定项目代码的混淆规则,让破解者难以阅读
res目录
以drawable开头的都是用来放图片的
以mipmap开头的都是用来放应用图标的(一般放在drawable-xxhdpi目录下)
以layout开头的都是用来放布局文件的
以values开头的都是用来放字符串,样式,颜色等配置的
String.xml中的字符串引用方式有两种:
代码中:R.string.name名
Xml中:@string/name名
如果引用的是图片资源可以替换成drawable,应用图标替换成mipmap,布局文件替换成layout,等等以此类推(相同类型不同目录下的xml文件引用前缀都是一样的,不一样的只有文件名)
四、日志工具
Android有五个日志级别,分别是log.v()、log.d()、log.i()、log.w()、log.e().级别依次递增
Log.v():打印最琐碎的日志信息,对应级别是verbose
Log.d():打印一些调试信息,对应级别debug
Log.i():打印一些比较重要的信息,对应级别info
Log.w():打印一些警告信息,对应级别warn
Log.e():打印一些错误信息,对应级别error
使用方法:例如Log.d(“MainActivity”,”onCreate execute”);
这个方法中有两个参数,第一个参数是tag,一般传入当前的类名,用于对打印出来的信息过滤,第二个参数是msg,即我们想要打印的内容。
五、Activity
1、Activity的启动方式分为两种:显式启动和隐式启动
显式启动:使用Intent对象,直接在Intent构造函数里指明要启动的activity
例如Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
startActivity(intent);
隐式启动:匹配action和category
例如:Intent intent = new Intent(“com.example.activitytest.ACTION_START”);
intent.addCategory(“com.example.activitytest.MY_CATEGORY”);
startActivity(intent);
Intent可以添加多个category,但是只能指定一个action
2、使用intent在activity传递数据:
FirstActivity中的代码:
Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
String data = “Hello SecondActivity!”;
intent.putExtra(“extra_data”,data);
startActivity(intent);
//使用putExtra方法,将信息装进intent中
SecondActivity中的代码:
Intent intent = super.getIntent();
String extraData = intent.getStringExtra(“extra_data”);
Log.d(“SecondActivity”,“extra data is :”+extraData);
//首先调用父类的方法得到intent,然后使用getStringExtra方法解析键为"extra_data"的字符串
3、返回数据给上一个activity:
Firstactivity中:
Intent intent = new Intent(SecondActivity.class);
startActivityForResult(intent,1);
//使用 startActivityForResult(intent,1);这个方法来启动activity,并传入一个请求码(唯一值)
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
super.onActivityResult(requestCode, resultCode, data);
while (requestCode = 1)//判断这个是不是我们之前传出去的请求码
if (resultCode == RESULT_OK)//判断返回数据时传入的处理结果
String returnData = data.getStringExtra(data_return);
Log.d(“FirstActivity”,“return data is :”+returnData);
//然后重写onActivityResult方法,然后调用父类的这个方法,在这个方法里面有3个参数,第一个就是请求码,第二个是第二个activity返回的处理结果,第三个就是响应的数据了,我们需要对请求码和处理结果进行判断,再来接收数据
SeconActivity中:
Intent intent1 = new Intent();
intent1.putExtra(“data_return”,“Hello FirstActivity”);
setResult(RESULT_OK,intent1);//第一个参数用于向上一个activity返回处理结果即resultCode,一般只使用RESULT_OK或RESULT_CANCELED
finish();
//使用putExtra方法往intent里传值,使用setResult方法返回处理结果和intent,最后调用finish()方法来结束这个activity
/*如果是按返回键来返回到上一个activity,我们可以重写onBackPressed()方法/
4、Activity的4种状态:
1、*运行状态*:当activity位于栈顶的时候,activity就是运行状态,系统最不愿意回收的就是运行状态的activity
2、*暂停状态*:当activity不处于栈顶的时候,但仍然可见的时候,activity就是暂停状态(例如对话框形式的activity),系统也不愿意去回收他,只有在内存极低的时候才会去回收他
3、*停止状态*:当activity不处于栈顶,且完全不可见的时候,就是停止状态,此时系统仍然会保留这种activity的状态和成员变量,但是并不一定,当系统需要内存的时候,这中activity就很有可能会被回收。
4、*销毁状态*:当activity从栈中被移出的时候,就是销毁状态,系统最喜欢回收这种状态的activity,以保证内存的充足
5、Activity的生存期:
Activity类中定义了7个回调方法,对应了Activity生命周期的每一个环节,分别是
onCreat()、onStart()、onResume()、onPause()、onStop()、onDestroy()、onRestart()方法
1、onCreat():activity第一次创建的时候被调用
2、onStart():在activity由不可见为可见的时候被调用
3、onResume():在activity准备与用户交互的时候被调用,并且此时Activity一定位于栈顶,且处于运行状态
4、onPause():准备去启动或者恢复另一个activity时候调用,这时候系统会将一些消耗CPU的资源释放掉,以及保存一些关键数据,这个方法执行要快,不然会影响新的栈顶activity的使用
5、onStop():在activity完全不可见的时候调用(如果启动的是对话框式的新activity则不会执行,但onPause()会执行,这是他俩的区别)
6、onDestroy():在activity被销毁之前调用,然后activity状态变成销毁状态
7、onRestart():在activity又停止状态变为运行状态的时候调用
6、Activity的启动模式:
Standard、singleTop、singleTask、singleInstance
1、Standard:标准的启动模式,activity每次启动都是一个新的,然后再入栈
2、singleTop:当activity位于栈顶的时候,再去启动这个activity不会再创建一个新的activity,而是直接去使用之前那个activity
3、singleTask:当去启动一个activity的时候,回去检查栈中是否有这个activity,如果有则将这个activity以上的activity全部出栈
4、singleInstance:这个模式下的activity会启用一个新的返回栈来管理这个activity(使用案例:使用这个启动模式的activity可以被其他程序共享,因为这个activity的返回栈是独立出来的)
UID进程之间可以相同,但是PID不一样,他是唯一标识的,UID相同的进程可以实现相互之间的数据共享,但是其他的比如类还是不可以共享的
六、AndroidManifest.xml文件
权限声明
Android将将权限分成了三类,普通权限和危险权限,以及以一类特殊权限(暂时不讨论),
普通权限:系统会帮用户自动申请此类权限(例如广播权限等)
危险权限:需要用户自己手动授权(联系人信息,地理位置等)
权限是按组划分的,有可能好几个权限名在一个组里,*原则上,用户同意某一个权限申请之后,同组其他的权限也会被自动授权*,但是Android系统可能随时调整权限的分组,所以我们不能基于此规则来实现功能逻辑。
使用危险权限时必须进行运行时权限处理
首先我们需要在AndroidManifest.xml文件中声明这个权限
首先我们需要判断用户是不是以及对应用受过权了
借助ContextCompat.checkSelfPermission(ThirdActivity.this,Manifest.permission.CALL_PHONE) 方法,传入两个参数,其中第一个参数为当前activity,第二个参数是我们请求的权限名(常量),然后将这个方法的返回值与PackageManager.PERMISSION_GRANTED做比较,如果相等则已授权,否则就是还没有授权,
如果没授权的话我们需要向用户申请权限,调用 ActivityCompat.requestPermissions(ThirdActivity.this,new String[]Manifest.permission.CALL_PHONE,2);方法,这个方法传入三个参数,第一个参数是activity实例,第二个参数是string数组,我们可以把权限名放在这个数组里面,第三个参数是请求码,要求是唯一值就行。
如果我们需要请求用户授权,调用requestPermissions方法后,需要重写 onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)方法,并在这个方法里判断用户是否授权
清单注册
四大组件Activity,Service,BroadcastReceiver,ContentProvider的使用必须在Androidmanifest.xml中注册,其中BroadcastReceiver分为动态注册和静态注册
Activity注册:
Service注册:<service android:name=“.SecondService”
BroadcastReceiver注册:
静态注册:
动态注册:
通过继承 BroadcastReceiver在activity内建立一个内部动态广播接收器类(TimeChangeReceiver),然后重写onReceive方法
然后在activity的onCreate()方法中实例化一个IntentFilter()对象,通过addAction()往这个对象传入一个常量,比如我们这里可以传入一个”android.intent.action.TIME_TICK”值,当系统时间发生变化的时候,系统发的正是一个值为这个的广播,也就是说我们想要监听什么广播,就往这里面添加相应的action,然后再把我们之前建立的广播接收器类实例化,最后调用registerReceiver(timeChangeReceiver,intentFilter)方法,这个方法需要接收两个参数,第一个就是我们自定义的广播接收器类的实例,第二个就是intentFilter实例。
*动态注册一定要记得取消注册!*
这里我们可以在onDestroy()中调用unregisterReceiver(timeChangeRe ceiver)
ContentProvider注册:注意android:authorities代表了权限,要和你设置ContentProvider的uri路径格式中:中的authority一致,否者会出现问题。
七、Service服务
1、了解Service在Android的定位
Service是Android中实现程序后台运行的解决方案,他不依赖于任何用户界面,他也不是运行在一个独立的进程中,而是依赖于创建service时所在的应用程序进程,当这个应用程序进程被杀掉时,service也会停止运行
Service不会自动开启线程,默认是运行在主线程中的,我们需要在service内部创建子线程,将执行的任务放在子线程中执行,否则容易导致主线程被阻塞
2、startService()和bindService()区别
-
启动方式:都是用来启动service的,但是bindService()获得的是一个持久连接
-
和activity联系:startService()启动的service如果activity销毁,仍可以保持运行,除非整个应用程序被杀掉,bindService()启动的service会跟activity一起销毁
-
数据交换方面:startService()启动的service不可以和activity进行数据交换,而bindService()可以
-
回调函数方面:startService()启动的service的回调函数是onStartCommand(),而bindService()是onBind()
-
结束service的方式:startService()是启动的service是调用stopService()或者stopSelf()方法,而bindService()是调用unBindService()方法。当同时调用startservice()和bindService()的时候,要同时满足上面两种结束方式,这个service才会被停止
3、Service生命周期
startService()→onCreat()(service创建)→onstartCommand()(service运行)→stopService()(service停止运行)→onDestroy()(service销毁)
bindService()→onCreat()(service创建)→onBind()(绑定service)→unBindService()→onUnBind()(解除绑定,service停止运行)→onDestroy()(service销毁)
生命周期理解
StartService,然后oncreate,onstartcommand,再绑定bindServic,然后onbind,onServiceConnection,再stopService方法,此时不回调任何方法,再unBindService,然后onDestroy
*StartService,然后oncreate,onstartcommand,,再绑定bindServic,然后onbind,onServiceConnection,再unBindService方法,此时不回调任何方法,再stopService,然后onDestroy
bindService,然后onCreat,onBind,onServiceConnection,再startService,然后onstartcommand,再stopService方法,此时不回调任何方法,再unBindService,然后onDestroy
bindService,然后onCreat,onBind,onServiceConnection,再startService,然后onstartcommand,再unBindService方法,此时不回调任何方法,再stopService,然后onDestroy
4、service的使用
1.关于startService的使用
首先在Androidmanifest.xml文件中注册这个service
首次创建时的代码放进MyService中的onCreat()方法中,要执行的业务逻辑代码放进onStartCommand()方法里
在TestActivity里使用这个service
//开启这个服务
Intent intent = new Intent(TestActivity.this,MyService.class);
startService(intent);
//关闭这个服务
Intent intent = new Intent(TestActivity.this,MyService.class);
stopService(intent);
\\2. bindService的使用
同样需要在Androidmanifest.xml中注册这个service
然后在MyService中新建一个内部类MyBinder继承Binder,在这个类里面执行业务代码,然后在onBind()方法中返回这个MyBinder内部类的实例
在TestActivity里使用这个service
首先创建一个匿名类new ServiceConnection()实现,并重写onServiceConnected(),onServiceDisconnected()方法,在onServiceConnected()方法中先获取MyBinder的实例,然后调用MyBinder内部类中的业务代码,这个匿名类的返回值类型为ServiceConnection
然后将这个类型的变量conn传进bindService方法和unBindService方法中,实现绑定和解绑操作
八、广播机制(broadcast)
标准广播和有序广播
标准广播:无序,异步执行,发送出去广播所有可以接收的broadcastReceiver几乎同时收到,效率高,且无法被拦截,
有序广播:有序,同步执行,一次只能被一个接收器接收,只有这个接收器逻辑执行完毕才会向下一个broadcastReceiver传送,效率低,可以被拦截
\\1. 学习broadcast的注册方式。
静态注册和动态注册
静态注册:在AndroidManifest.xml中注册,
在Androidmanifest.xml中的intentFilter标签中添加一个要监听的action标签,如果是“危险”的广播还需要进行权限申明
动态注册:在代码中注册
使用intentFilter过滤器,然后添加一个action值,然后实例化一个broadcastReceiver对象(此处测试类中重写的onReceive方法中只实现了一个Toast),再调用registerReceiver()方法将这两个参数传递进去。然后就实现了动态广播注册
2. broadcast使用的注意事项
标准广播和有序广播的实现方式基本一致,只是最后发送调用的方法不同
发送标准广播:sendBoardcast(intent)
发送有序广播:sendOrderedBroadcast(intent,null)
在标签里面设置优先级,android:priority越高的接收器越先收到,同等优先级情况下,谁先启动的快谁先收到广播
静态注册的广播接收者无法收到隐式广播,此时我们需要指定包名,将这条隐式广播变成显式广播
*动态注册的广播要手动移出广播接收器*
3. 外部broadcast以及本地广播的使用
外部broadcast:程序之外的广播,例如系统广播等等,如前面动态注册和静态注册的使用
本地广播:需要使用到LocalBroadcastManager的实例(instance = LocalBroadcastManager.getInstance(this);),然后通过这个实例再去调用registerReceiver,即instance.registerReceiver(),里面传递的参数跟前面动态注册的参数是一样的。
4. SharePrefence(轻量级存储)的使用方式
适合单进程,小批量的数据存储与访问,因为他是基于单个xml文件的,一次性加载进内存的。属于全局可读写。
使用方式:我们首先需要获取一个SharedPreferences对象,有两种方式可以得到这个对象
Context类中的getsharedPreferences()方法,两个参数,第一个指定文件名(若文件不存在则会创建一个),第二个指定操作模式
Activity类中的getPreferences()方法,只有一个操作模式参数,文件名默认使用当前activity的类名
存储数据:
使用以上方式获得一个sharedPreferences对象后,调用edit()方法,然后获得一个SharedPreferences.Editor对象,这个对象中提供了putString,putInt,putBoolean等一系列方法,都是以键值对的形式存储数据,然后使用apply()或者commit()方式提交,apply()是异步的,commit()是同步的,推荐使用apply()方法
文件放在了Device File Explorer文件管理器下面的data/data//shared_prefs下了
取出数据:
也是先获得一个sharedPreferences对象,然后再调用这个对象的getString(),getInt(),getBoolean()方法,这些方法需要两个参数,第一个参数是键,第二参数指定若是取出数据失败返回的默认值
5.SharePrefence数据共享
两个应用(A和B)数据共享的前提是有 相同的sharedUserId,即首先我们需要在manifest.xml文件中配置这个属性android:sharedUserId=“com.xxx”.
然后在A应用中使用sharedPreferences存储数据(参考上面的存储数据)
接着在B应用中取出这些数据
首先创建一个Context 类型的对象packageText,然后调用createPackageContext(“com.netease.nim.demo”, CONTEXT_IGNORE_SECURITY);方法创建一个包上下文,把返回值赋值给packageText(此处操作需要在try catch中捕获异常)
然后通过这个packageText去调用getSharedPreferences(“userlists”, Context.MODE_MULTI_PROCESS);这个方法,返回值是SharedPreferences类型的,然后再通过这个返回值调用getString(),getBoolean()等方法得到A应用中存储的值(一样需要传入一个键,即A中存数据使用的键)
九、ContentProvider
ContentProvider概念:
翻译成中文是内容提供者,他可以实现应用之间的内容共享,可以指定哪部分具体的数据进行共享,而文件存储和sharePreferences是两种全局的可读写模式,相比较来说ContentProvider就可以保证数据没有泄露的风险。
ContentProvider使用表的形式来组织数据,类似一个单数据库表
每个ContentProvider都有一个唯一的公开的内容URI,用来指定他的数据集
一个标准的URI格式如下:
Content://com.example.contentProvider.accessProvider/table
1. contentProvider的使用
用法:用法一般有两种
①一种是使用现有的ContentProvider读取和操作相应的应用程序中的数据
查询:
ContentResolver.query( URI, projection, selection, selectionArgs, sortArgs)或者Activity.managedQuery(URI, projection, selection, selectionArgs, sortArgs)方法,这两个方法的参数一模一样,返回值也是相同的,不同的是activity可以对cursor对象管理,比如activity暂停的时候卸载cursor对象,restart的时候再重新查询。还可以调用Activity.startManaginCursor()方法来管理一个没有activity管理的cursor对象
参数解读:
第一个参数:URI指定某个应用程序下的某一张表
第二个参数:projection指定查询的列名
第三个参数:selection指定约束条件(对应SQL中where的约束条件)
第四个参数:selectionArgs给where中的占位符提供具体的值
第五个参数:sortOrder指定查询结果的排序方式
查询指定行的值,需要用到ID值,如果我们不想手动去拼接URI可以使用ContentUris.withAppendedId(URI,ID)方法
示例代码如下:
public class ForthActivity extends AppCompatActivity
private List<String> contactList = new ArrayList<String>();
private ArrayAdapter<String> adapter;
private static final String ForthActivity = "ForthActivity";
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.forth_activity);
Log.d(ForthActivity, "执行了ForthActivity中的onCreate方法");
Button readContacts = findViewById(R.id.readContacts);
readContacts.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
if (ContextCompat.checkSelfPermission(ForthActivity.this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(ForthActivity.this, new String[]Manifest.permission.READ_CONTACTS, 1);
else
readContacts();
);
Button accessProvider = findViewById(R.id.accessProvider);
accessProvider.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
ContentResolver contentResolver = ForthActivity.this.getContentResolver();
Uri uri = Uri.parse("com.example.contentProvider.provider1/table1/1");
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while (cursor.moveToNext())
int num = cursor.getColumnIndex("1");
Log.d("forthActivity", "num"+num);
cursor.close();
);
private void readContacts()
ContentResolver contentResolver =getContentResolver();
Uri uri1 = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursor = contentResolver.query(uri1, null, null, null, null);
while (cursor.moveToNext())
@SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
@SuppressLint("Range") String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.d("forthActivity", "name:"+name+"电话号码:"+number);
cursor.close();
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
case 1:
if (permissions.length!=0 && grantResults[0] != PackageManager.PERMISSION_GRANTED)
Toast.makeText(ForthActivity.this, "获取权限后重试", Toast.LENGTH_SHORT).show();
break;
readContacts()方法解读:首先获得一个URI,然后再获得一个contenResolver对象,再通过这个对象调用相关的查询方法,将URI和其他参数传进这个查询方法里,返回一个cursor对象(游标、指针),然后通过这个指针去遍历这个结果集
增加:
调用contentResolver().insert(URI, values)方法
ContentValues values = new ContentValues();
values.put(“ID”, “Abraham Lincoln”);
Uri uri = ContentResolver().insert(URI, values);
解读:创建一个contentvalue对象,然后以键值对的形式往里面put值,键是列名,然后调用insert()方法,传入URI和这个put了值的values对象作为参数,这个插入方法会有一个返回结果,我们可以根据这个返回结果来判断是否插入成功,一般插入成功会返回该行的URI
修改:
Update()方法
int rowsUpdated = contentResolver().update(
URI,
updateValues,
selectionClause,
selectionArgs);
参数含义:URI,更新的值,约束条件,给where中的占位符提供具体的值
删除:delete()方法
②另一种是创建自己的ContentProvider,给程序的数据提供外部访问接口
在自定义的ContentProvider中有六个需要重写的方法,其他五个比较常见,分别是创建和增删改查,最后还有一个getType()方法,这个方法用来返回uri对象所对应的MIME类型
指定对应的uri地址,然后这写uri地址做逻辑判断,等到其他程序来调用的时候,通过这些逻辑判断来进行安全控制和访问内容的限制
public class AccessProvider extends ContentProvider
public AccessProvider()
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static
uriMatcher.addURI("com.example.contentProvider.provider1",
"table1", 1);
uriMatcher.addURI("com.example.contentProvider.provider1",
"table1/#", 2);
uriMatcher.addURI("com.example.contentProvider.provider1",
"table2", 3);
uriMatcher.addURI("com.example.contentProvider.provider1",
"table2/#", 4);
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
@Override
public String getType(Uri uri)
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
@Override
public Uri insert(Uri uri, ContentValues values)
// TODO: Implement this to handle requests to insert a new row.
throw new UnsupportedOperationException("Not yet implemented");
@Override
public boolean onCreate()
// TODO: Implement this to initialize your content provider on startup.
return false;
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
switch (uriMatcher.match(uri))
case 1:
Log.d("AccessProvider", "进入了第一个判定条件");break;
case 2:
Log.d("AccessProvider", "进入了第二个判定条件");break;
case 3:
Log.d("AccessProvider", "进入了第三个判定条件");break;
case 4:
Log.d("AccessProvider", "进入了第四个判定条件");break;
default:
break;
throw new UnsupportedOperationException("Not yet implemented");
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs)
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
如何使用,见①中代码
访问危险权限需要在manifest.xml中申明,提供接口和访问数据上面有提到
十、五大布局的使用以及约束布局的使用
1、了解各个布局的区别以及如何使用
布局包含控件,布局与布局之间是可以嵌套使用的,可以理解成控件是布局里面的最小组成单元。
Android的五大布局+后来的constraintLayou(约束布局)
五大布局分别是:LinearLayout,relativeLayout,frameLayout,tableLayou(淘汰),absoluteLayou(淘汰)
2、LinearLayout(线性布局):
这个布局有horizontal(水平排列)和vertical(垂直排列)两种方式,默认就是垂直排列,水平排列的时候,控件的宽度不能指定为match_parent,垂直排列的时候控件的高度不能指定为match_parent
里面比较常用的属性:
layout_gravity:他是用来指定控件在布局中的对齐方式的,值得注意的是当linearLayout的布局方式为水平的时候,这个属性只有垂直对齐才有效,当linearLayout的布局方式为垂直的时候,这个属性只有水平对齐才有效
Layout_weight=”1”:以LinearLayout的水平布局为例,如果有三个按钮,我们可以将这三个按钮的宽度属性指定为”0dp”,然后再使用这个属性,意思是说这三个按钮水平分布平分水平的宽度,这个1其实就是权重
3、relativeLayout(相对布局):
这个布局他可以通过相对定位的方式来让控件出现在任何位置
比较常用的属性:
layout_alignParentleft,layout_alignParenttop…和哪边一直这里是左边和上边一致
Layout_above=”@id/button1” 在哪个控件的上面
Layout_below=”@id/button1” 在哪个控件的下面
Layout_toLeftOf=”id/button1” 在哪个控件的左边
Layout_toRightOf=”@id/button1” 在哪个控件的右边
4、frameLayout(帧布局):
这里面的控件默认会摆放在布局的左上角,他的定位方式比较少,比如:
Layout_gravity=”left”:指定控件居左对齐
Layout_gravity=”right”:指定控件居右对齐
十一、自定义Shape资源,drawable资源等
1、了解drawable文件夹中可自定义的文件种类
Drawable是什么,翻译成中文意思是说能画的东西,专业的解释是:一种可以在Canvas上进行绘制的抽象的概念,颜色,图片都可以说是drawable,可以通过xml文件定义,也可以通过代码创建,所有的实现的drawable都是Drawable这个抽象类的子类。
drawable文件下可以存放图片资源,例如*.jpg,.png,.gif,
还可以放xml文件,其中常用xml类型的资源文件有:
ShapeDrawable:通过颜色构造的图形,可以是纯色的图形,也可
Android 面试题总结之Android 基础
Android 面试题总结之Android 基础Activity(一)
转眼间毕业好久了,写程序也很久了,从高中就一直写到现在好多年了啊,学习了很多东西,把之前整理的资料和知识点慢慢分享出来。这里主要总结Android可能出的面试的题目比较全面\\详细,持久更新,也欢迎大家补充,纠正,批评。
在阅读过程中有任何问题,请及时联系。
本章系《Android 之美 从0到1 – 高手之路》Android基础Activity 总结了Android 开发者面试比较常见的Activity面试问题。希望对广大Android 开发者,有所帮助。
以上是关于Android基础知识点学习总结的主要内容,如果未能解决你的问题,请参考以下文章