Android学习笔记
1、10个基本简单的linux
- mkdir 创建文件夹
- rmdir 删除文件夹
- rm 删除文件
- touch 创建文件
- cat 查看文件
- find查找目录
- mv移动(修改)文件
- cp 拷贝文件
- cd 切换当前目录
- tail 查看文件尾部
- ls 列出文件清单
- reboot重启
- ps 查看系统进程
2、adb命令adb
- device 查看连接计算机的设备
- adb reboot 重启设备
- adb reboot bootloader 刷机模式
- adb logcat 查看
- logadb kill-server 终止进程服务
- adb start-server 重启进程服务
- adb install xxx.apk安装
- apkadb unstall xxx.apk 卸载apk
- adb connect ip地址 连接设备
- adb shell kill [pid] 杀死进程
- adb shell ps 查看进程
- adb shell ls 列出目录下的文件夹
- adb logcat -c 清除log缓存
3、ANR(Application not Responding) 如何避免?
将耗时的操作,比如:访问网络、Socker通信、大量查询SQL语句都放到子线程中去。
通过handle.sendMessage、runonUITread、AsyncTask等方式更新UI。
4、一条最长的短信息约占多少个byte?
国内三大运营商通常情况下中文70、英文160个。包括标点
5、如何判断是否有SD卡:
Environment.getExternalStorageState().equals(MEDIA_MOUNTED)
6、Android程序与Java程序的区别:
Android程序用android sdk开发,
java程序用 java sdk开发。
Android程序引用了大部分的Java SDK.
7、启动应用后,改变系统语言,应用的语言会改变么?
一般是不会的,只有重启应用才能改变应用语言,除非应用做了国际化处理。
8、介绍下adb、ddms、aapt的作用:
adb:(Android debug bridge)Android调试桥
ddms:(Dalvik DeBug Monitor Service)程序执行查看器(dalvik调试监视服务)
aapt:Android sdk中提供的一个小工具:可以查看、创建、更新ZIP格式的文档附件
9、ddms和traceview的区别:
ddms是一个程序执行查看器,在里面可以看见线程和堆栈等信息,
traceview是程序性能分析器。PS:traceview是Android平台特有的数据采集和分析工具。
10、Activity:四大组件之一,是Context的子类,通常一个用户交互界面对应一个activity。
Activity的生命周期:
- onCreate():表示Activity正在被创建,Activity不可见,可做一些初始化工作
- onStart():Activity正在被启动,Activity可见,但还处于后台,无法与用户交流
- onResume():Activity可见,在前台并开始活动,可初始化一些资源,比如打开相机或开启动画
- onPause():Activity正在停止,Activity还可见,可做一些保存数据、停止动画及资源回收操作。
- onStop():Activity即将停止,Activity不可见状态,在后台运行,可做一些轻量级的回收操作。
- onDestroy():Activty即将销毁,Activity不可见状态,做最终的回收工作和最终资源的释放
- onRestart():可见状态,表示Activity正在被启动,一般发生在用户打开一个新的Activity,原本Activity执行onPause()、onStop()方法,当重新回到这个Activity时候调用
参考博客 :https://blog.csdn.net/csdn_aiyang/article/details/72866032
保存Activity的状态:
重写onSaveInstanceState()方法,接受一个Bundle类型的参数,可以将状态存储到Bundle对象中,当重启activity调用它onCreate()方法时,Bundle将作为实参传递给onCreate()横竖屏切换时Activity的生命周期:不设置Activity的android:configChanges时,切屏会重新调用各个生命周期。切横屏会执行一次,竖屏两次设置android:configChanges=“orientation”时,切屏也还会调用各个生命周期,切横、竖屏时只会执行一次设置android:configChanges=“orientation|keyboardHidden”时,不会重新调用各个生命周期,只会执行onConfigurationChanged方法将Activity设置成窗口的样式:
在Manifest中将主题设置成Dialog样式如何退出Activity?如何安全退出已调用多个Activity的Application?
(1) 一般情况下,用户按back键就可以退出Activity,直接调用finish().
(2) 记录打开的activity,每打开一个就记录下来,在需要退出的时候,关闭每一个activity即可
(3) 发送特定广播,在需要退出的时候,发送一个特定的广播,每个Activity收到广播的时候,关闭即可。
(4)在打开新的Activity时候,使用startActivityforresult,在onActivityResult中处理,递归关闭。
Activity的四种启动模式:
standard:每启动一次都要创建新的实例,不管实例有没有存在。
singleTop:栈顶复用,若在栈顶就不生成新的实例,如果在栈顶就调用onNewIntent复用。应用在在当前的Activity中启动同类型的Activity
singleTask:栈内复用,只要存在栈内就不创建新的实例,其余实例出栈,应用在主页singleInstance:单例模式,系统会给该Activity单独创建一个栈
11、Service:四大组件之一,主要执行一些不需要与用户交互且要求长期运行的任务,后台任务的处理Service是否在main thread中执行,service里是否能执行耗时操作?默认情况下,service和activity是运行在当前app所在进程的main thread里面,所以service里面不能执行耗时的操作。特殊情况下,可以在清单文件配置service执行所在的进程,让service在另外进程中执行。Activity如何绑定service,如何在Activity中启动自己对应的Service?Activity通过bindService(Intent service,ServiceConnection conn,int flags)跟service绑定,,当绑定成功后service会将代理对象通过回调的形式传给conn,就能拿到Service提供的服务代理对象。在Activity中通过startService()和bindService()来启动服务,想要获取Service服务对象就通过bindService,若仅仅想要开启一个后台服务,就是要startService()StartService启动服务,调用者和服务之间没有关联,如果是调用者直接退出没有调用stopService的话,Service一直在后台运行,用BindService启动服务,调用者和服务绑定了,调用者一旦退出,Service也就终止。Service生命周期:非绑定模式:onCreate()、onStartCommand()、onDestroy()绑定模式:onCreate()、onBind()、onUnbind()、onDestroy()什么是IntentService,有何有点?IntentService是Service的子类,可以根据需要处理异步请求(表示为Intent)。重复调用StartService()或bindService()会怎么样?
第一次调用服务时候,会先调用onCreate()再调用onStartCommand()。若在这个生命周期内,再次启动服务,则直接调用onStartCommand(),onBind()也只执行一次Actiivty、Service、Intent的关系:Activity和Service都是四大组件,都是Context的子类ContextWrapper的子类,Activity负责用户界面的交互和显示,Service负责后台任务的处理,Activity和Service通过Intent传递数据,Intent可看成是通信使者。
Service和线程都是开启后台服务,什么时候使用Service和线程:
1、Service默认运行在主线程中,执行耗时操作时在线程中开启。
2、Service优先级高于后台挂起的Activity或者Thread,所以当系统资源不够时候优先杀死Activity和Thread。
3、Thread运行独立于Activity,也就是当Activity被finish之后,如果没有主动停止Thread或者Thrad里面的run方法未执行完,Thread也会一直执行,这时候,当Activity被finish之后不再持有该线程,无法控制之前创建的线程,而Service可以。
12、BroadCastReceiver :四大组件之一,主要用于接收系统或app发送的广播事件。可以进行进程间通信分为有序广播和无序广播:无序广播:完全异步,可以被所有广播接收者收到,效率高,但是无法将处理结果传给下个接收者,没有顺序,无法被截断。有序广播:同步执行的广播,广播发出后同一时间只能有一个广播接收器接收到广播,当优先级高的广播接收器的onReceiver方式运行结束后,广播才会继续,当前广播也可以截断广播,不继续向下传递。引用广播的用意:(1)程序间的互通消息(2)Android的四大组件本质上也就是为了实现移动设备上的MVC架构,可以方便几大组件的信息和数据交互注册广播的两种方式:静态注册:在清单文件中为BroadcastReceiver注册,使用标签声明,并在标签内标签设置过滤器。生命周期伴随整个应用。=>常驻型广播,应用程序关闭后还是会收到广播动态注册:在代码中定义并设置好IntentFilter对象,然后在需要注册的地方调用Context.registerReceiver()方法,调用Context.unregisterReceiver()方法取消注册。=>非常驻型广播,跟随Activity生命周期,当程序关闭时,该接收器会被销毁PS:BroadcastReceiver生命周期很短,从接收广播创建到onRecrive()方法结束后销毁。广播接收者中不要做一些耗时操作,会弹出ANR耗时较长的工作最好在服务中完成
动态广播注册在onResume和onPause中注册或销毁,因为onpause在App杀死前一定会被执行,从而保证广播在App在死亡前进行销毁,防止内存泄漏,再者,当系统内存不足时,在回收Activity占用的资源时,activity在执行完onPause后就会被销毁。
13、ContentProvider:四大组件之一,应用程序之间共享数据的接口使用方法:自定义一个类继承ContentProvider,然后覆写query、insert、update、delete等方法,第三方可以通过ContentResovler来访问该Provider。Android的数据存储方式:File存储、ContentProvident存储、SharedPreference存储、SQLiteDateBase存储、网络存储ContentProvider和sql的区别:ContentProvider屏蔽了数据存储的细节,只需要关心操作数据的uri就可以了,它可以实现不同app之间的共享,sql只能查询本应用下的数据库说说ContentProvider、ContentResolver、ContentObserver之间的关系:ContentProvider 内容提供者,用于对外提供数据ContentProvider.notifyChange(uri)发出消息ContentResolver:内容解析者,用于获取内容提供者提供的数据ContentObserver:内容监听器,可以监听数据的改变状态。ContentResolved.registerContentObserver()监听消息
14、Android中的几种布局文件线性布局(LinearLayout):水平/垂直相对布局(RelativeLayout):根据参照物的位置来定位控件的位置框架布局(FrameLayout):放入的控件都被放到左上的区域。表格布局(TableLayout):通过表格方式布局(行/列)来布局控件的位置绝对布局(AbsoluteLayout):采用坐标轴的方式定位控件约束布局(ConstraintLyout):控件之间存在相应的位置关系。优点:减少布局层级使用(复杂布局)以及速度快,性能高Padding和Margin区别:padding站在父view的角度描述问题,规定它里面的内容与这个父view边界的距离,margin是站在自己的角度描述问题,规定自己上下左右的距离。 ?padding是内边距,margin是外边距
15、ListViewListView如何提高效率(1)复用ConvertView(优化加载布局问题):减少findviewById的使用次数,每个item都会创建一个view对象,这非常耗内存,为了节约内存可在converView不为null的时候复用。(2)自定义静态类ViewHolder(优化加载控件):缓存item条目(优化getView()中每次调用findviewById方法来获取一次控件的代码)(3)使用分页加载:优化查询数据,优化内存(4)使用分段加载:优化用户体验,比如10000条数据,要全部加载完才显示,会影响用户体验ListView数据集发生改变后,如何更新ListView?调用adapter的notifyDataSetChanged方法如何定位到指定位置:listview.Selection(2)
16、Java中引用类型都有哪些?作用是什么?几种引用类型:强引用、软引用、弱引用、虚引用引用类型的作用:使得程序可以更好的控制对象生命周期,帮助缓解和处理内存泄漏的问题。强引用:必不可少的,Object object=new Object();这是一个强引用,若一个对象具有强引用,垃圾回收器绝不会回收它,哪怕内存控件不足时,java虚拟器宁愿抛出OutOfMemoryError错误,使程序异常终止也不会回收。软引用:可有可无,当内存空间足够了就不会回收,当内存空间不足时,就会回收这些对象的内存。软引用用来实现内存敏感的高速缓存弱引用:可有可无,不管内存足够与否,都会回收它的内存,它与软引用的区别在于弱引用的对象具有更短暂的生命周期虚引用:虚引用并不会决定对象的生命周期,任何时候都可能被垃圾回收。主要用来跟踪垃圾回收的活动。
17、JNI(Java Native Interface)和NDK(Native Development Kit)JNI作用:使得Java与本地其他语言类(C/C++)交互,它是属于Java的,与Android没有关系。NDK:Android的一个工具开发包,快速开发C、C++的动态库 。
18、Intent传递:可以传递哪些数据类型:java的基本数据类型和String以及他们的数组格式,还传递Serializable和Parcelabele接口的对象
19、Serializable和Parcelable的区别:
1.在使用内存的时候,Parcelable(直接在内存中读写)比Serializable(使用IO读写存储在硬盘上)性能高,所以推荐使用Pacelable.
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC(垃圾回收机制)
3.Parcelable不能使用在要将数据存在磁盘上的情况
4.Parcelable是android的,Serializable是java的
20、Intent和IntentFilter的区别Intent代表了Android应用的启动意图,Android应用根据这个Intent来启动指定组件。IntentFilter相当于Intent的过滤器,应用开发完后,需要用IntentFilter告诉Android系统能处理哪些隐式的Intent请求,主要通过data、category、action三方面
21、FragementFragment和Activity间的传值:Fragment和Activity绑定后,在Fragment中可直接通过getActivity()方法获取到其绑定的Activity对象,这样就能调用到Acitivity的方法了,在Activity中通过如下方式获取到Fragment:FragmentManager manager=getFragmenManager(); Fragment fragment=manager.findFragmentById(id);或者fagment=manager.findFragmentByTag(tag);获取到fragment后就可以调用Fragment的方法。Fragment生命周期:创建时会执行的方法:onAttach():fragment关联activity,在此可与activity通信。onCreate():系统创建fragment时使用,实例化一些变量,主要是暂停、停止时想保存的数据。onActivityCreate():在onCreate()执行之后调用,onCreateView():加载fragment布局变得可见时会执行:onStart():Fragment启动时回调,此时Fragment可见onResume():Fragment进入前台,可再此做一些onpause()或onStop()方法中释放的资源。进入后台会执行的方法:onPause():一般指用户离开这个fragment(非销毁),在此可做一些数据存储、动画停止等操作。onStop():Fragment不可见,可做一些资源释放操作最后销毁:onDestroyView():移除布局,销毁相关联的布局,清除与视图相关的资源。onDestroy():销毁Fragment,回收工作和最终资源释放。onDetach():activity与fragmnet解除关联
22、如何对Android应用进行内存性能分析:出现卡顿等原因:在UI线程中做轻微耗时操作导致布局Layout过于复杂,无法再16ms内完成渲染同一时间动画执行的次数过多,导致CPU或GPU负载过多view过度绘制View频繁的触发measure、layout内存频繁触发GC过多冗余的资源及逻辑导致加载和执行缓慢ANR如何进行性能分析:ddms(程序执行查看器)的traceview、heap、allocation tracker等工具traceview:程序性能分析器heap:检查代码中可能有内存泄漏的地方allocation tracker:什么情况下会导致内存泄漏:资源释放问题:Context、Cursor、IO流的引用,资源得不到释放对象内存过大问题:保存了多个耗用内存过大的对象,例如Bitmap、xml文件,造成内存超出限制static引用资源耗费过多的实例,例如:static Context线程导致内存泄漏
23、避免OOM(Out Of Memory:内存溢出)异常:
分为内存泄漏(申请使用完的内存没有释放)和内存溢出(申请的内存超过了JVM能提供的大小)
图片过大导致OOM时:等比例缩小图片或者是采用软引用及时进行recyle()操作界面切换导致的OOM:若布局中有背景图之类的,放到onCreate()中去处理,在activity中的onDestroy中drawable.setCallback(null)查询数据库记得关闭游标Bitmap对象不再使用时调用recycle()释放内存
24、Android如何捕获未捕获的异常自定义一个Application,继承Application实现UncaughtExceptionHandler,重写onCreate()和uncaughtException()方法,然后在Manifest中配置该Application25、Android屏幕适配dp:dip的缩写,指密度无关的像素(px)dp适配:dimens适配:layout适配java代码适配xml布局中weight权重适配屏幕适配的技巧:手机自适应情况主要分为:横竖屏的切换(Manifest中配置configChange,然后在activity中重写onConfigChanged方法)、分辨率大小的不同(可设置weight权重设置)
25、AIDL(android interface definition language):步骤:
服务端:
1.首先创建aidl文件,定义提供的接口
2.创建一个自定义Service继承Service,在里面创建一个类继承刚创建AIDL的Stub类并实现aidl中定义的方法,在onBind返回内部类的方法。
客户端:
3.绑定服务端的Service,使用asInterface()将服务端的Binder对象转换成AIDL接口所属类型。然后调用AIDL中的方法PS:通过bindService(Intent,ServiceConnect,int)绑定远程服务,bindService中有一个ServiceConnect接口,我们需要覆写onServiceConnected(ConponentName,IBinder)方法,IBinder就是在AIDL中定义的接口。
26、自定义控件自定义组合控件:自定义组合控件就是把多个控件作为一个整体看待、处理。自定义view步骤:1.自定义View的属性:在res/values/下建立一个attrs.xml,在里面定义属性和声明整个样式,然后在布局文件中声明自定义的view,在自定义View的构造方法中获取自定义的样式2.重写onMeasure()测量view(宽高)和它的内容,每一个measureSpec由一个尺寸(size)和模式(model)3.重写onDraw()方法,使用Canvas绘制图形
27、Android中的事件处理Handle机制:Android中的主线程(UI线程)用来创建、更新UI,耗时操作需要在子线程中处理,处理完后为了防止UI处理逻辑混乱,Android只允许主线程修改UI,Handle充当桥梁。使用步骤:将Handle声明在Activity中,覆写Handle的handleMessage()方法,当子线程调用handle.sendMessage()方法后,handleMessage方法就会在主线程中执行。
PS:MassageQueue:消息队列,它的内部存储了信息,Looper对象对该线程的MessageQueue进行管理。
Looper: 无限循环的方式去查询消息队列中是否有消息。每个线程都有自己的Looper对象,通过ThreadLocal获取当前线程的looper,主线程自动创建Looper对象,而其他线程在使用的时候需要自行创建。通过Looper.prepare()为当前线程创建一个Looper,通过Looper.looper()来开启消息循环。退出looper可通过quit(直接退出looper)和quitSafely(处理消息完后才退出)
Message:MessageQueue中存储的对象。ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,存储后也只能在指定的线程中获取到数据。通过ThreadLocal来获取到当前线程的Looper
28、事件分发机制事件分发中的onTouch和onTouchEvent区别,如何使用?
onTouch优先于onTouchEvent执行,若在onTouch中通过返回true将事件消费掉,onTouchEvent将不会再执行。onTouch得到执行需要两个执行条件,一个是onTouchListener的值不能为空,第二是当前点击的控件必须是enable的。
描述一下事件的分发流程:事件收集之后最先传递给Activity,然后依次向下传递,Activity->PhoneWindow->DecorView->ViewGroup->View如果事件被消费,意味着事件信息传递终止如果事件没有被消费,事件会回传给Activity,如果Activity也不需要就被抛弃判断事件是否被消费是根据返回值,而不是根据你是否使用了事件
viewGroup的事件为三个:dispatchTouchEvent(事件分发)、onInterceptTouchEvent(拦截事件,事件返回true表示被消费)、onTuchEvent(处理事件)。 View的事件只有:dispatchTouchEvent()、onTouchEvent()
首先是Activity的事件分发:调用Activity的dispatchTouchEvent()->getWindow().superDispatchTouchEvent()->Decor.superDispatchTouchEvent()->若返回true,当前事件被消费,则事件分发结束。若返回false,继续向下分发。调用ViewGroup的。
29、Android数字签名在Android系统中,所有安装到系统中的应用程序都必有一个数字签名,数字证书的私钥保存在程序开发者手中。用来标识应用程序作者和应用程序之间建立信任关系。
30、Android中的动画系统动画:Tween(补间)动画:这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化Frame(逐帧)动画:传统动画,类似电影补间动画缺点:作用对象局限,只能作用在视图View上没有改变View的属性,只改变视觉效果动画效果单一Android 3.0之后加入了属性动画:可以对任意对象的属性进行动画而不仅仅是View。通过AnimatorSet类和xml文件的set标签都可以改变对象的多个属性,实现动画效果。=>AnimatorSet通过before、with、after三个方法组合多个属性动画,with表示与给定动画同时执行,before在给定动画执行前执行,after在给定动画执行之后执行ObjectAnimatorValueAnimator:ObjectAnimator的父类,ObjectAnimator和ValueAnimator传入的都有一个TypeEvaluator类型的参数,只是一个接口,里面也只有一个
31、如何修改Activity进入和退出的动画。
1.定义Activity的主题,在Manifest中给指定的Activity指定theme。
2.覆写overridePendingTransition方法
32、多线程和异步加载多线程三种方式:
1.new Thread(new Runnable),把run()方法写在线程里
2.让Activity实现Runnable接口,把run方法单独提出来
3.利用线程池ExecutorService接口创建多线程异步任务三种方式:
1.AsyncTask:
doInBackgound()是继承AsyncTask必须要实现的,运行后台,做耗时操作。
onPostExecute()在主线程中运行,写开始提示代码。
publishProgress()更新进度,给onProgressUpdate()传递参数。
onProgressUpdate()在publishProgress()调用完被调用,更新进度
2.Thread的两种方式:
(1)public class MyThread extends Thread{},然后调用的时候MyThread.start()。
(2)public class MyRunnable implement Runnable{}, 使用的时候调用new Thread(new MyRunnable()).start()
3.IntentService:具有Service一样的生命周期,提供了后台线程中的异步处理机制,
使用public class MyIntentService extends IntentService{}。
启动Intent in=new Intent(ServiceActivity.this,MyIntentService.class);startService(in)
33、都使用过哪些框架、平台EventBus、mob(短信验证)、Retrofit、butterknife、picassio、photoview
34、EventBus:自定义一个事件类:例如UserBean要接收消息的页面:注册:EventBus.getDefault().register(this)接收消息的方法:onEvent(UserBean bean)取消注册:EventBus.getDefault().unregister(this)发送消息的页面:EventBus.getDefault().post(new UserBean(xxxxx))
35、Context从Android系统的角度来理解:Context是一个场景,描述的是一个应用程序环境的信息,即上下文,代表与操作系统的交互的一种过程。从程序的角度上来理解:Context是个抽象类,而Activity、Service、Application等都是该类的一个实现,也就是说是它子类
36、RecycleView对于ListView的差异:LayoutManager管理各种类型的布局加入Holder来管理布局和布局复用,不同Type的View都要创建各自的Holder没有现成的ItemClick回调丰富的数据刷新方法可自定义分割线
37、如何从网络上加载一张图片显示到界面上原生方法:使用BitmapFactory.decodeStream(inputString)方法将图片转换成bitmap,然后通过imageview.setImageBitmap()将图片设置到Imageview中使用第三方框架:Picasso、ImageLoader等
38、Activity之间的通信方式:
startActivityforesult()启动通过广播形式Intent跳转时携带数据数据存储方式:Sharedpreference等
39、Android虚拟机DVM 和java虚拟机JVM的区别Dalvik基于寄存器,而JVM基于栈,基于寄存器的虚拟机编译时花费时间更短DVM执行.dex格式的字节码,JVM执行.dass格式的字节码
40、MVC与MVP:
MVC:M:模型层,负责处理数据的加载或者存储V:视图层,负责界面数据的展示,与用户进行交互C:控制器层,负责逻辑业务的处理基本流程:首先视图接收用户的输入请求,然后将请求传递给控制器,控制器再调用模型来处理用户请求。在控制器的控制下,将处理后的结果交给视图进行格式化输出给用户。
MVP:M:数据层,负责数据的加载或存储V:视图层,负责界面数据的展示,负责与用户交互P:中间者,绑定Model层和View层,是Model和View之间的桥梁MVC和MVP的区别:MVP中的View并不直接使用Model,它们之间的通信是通过Present来进行的,而MVC中View直接从Model中读数据而不是Controller
41、https和http的区别超文本传输协议Http被用在Web浏览器和网站服务器之间传递信息,以明文方式发送内容,不提供任何方式的数据加密。安全套接字层超文本传输协议HTTPS,在HTTP基础上接了SSL协议,为浏览器和服务器之间的通信加密
42、UDP(用户数据报协议)和TCP(传输控制协议)基本区别TCP面向连接、传输可靠,用于传输大量数据,速度慢,建立连接需要开销较多
UDP面向非连接,传输不可靠,用于传输少量数据,速度快TCP如何保证可靠数据传播:
(1)将数据截取为TCP认为合理的长度。
(2)当TCP发出一个段后它会开启一个定时器,当不能及时收到时候,进行重新发送(超时重发)。
(3)对于收到的请求,进行回应)
(4)对于失序的数据进行重排序。
(5)丢弃重复数据
43、Socket基本实现原理基于TCP协议的Socket:
服务端:
1、服务端声明一个ServiceSoket,并指定端口号:ServiceSockt mserviceSoket=new ServiceSocket(8080)
2、调用accept()方法接收数据:Socket socket=mserviceSoket.accept()
3、接收到数据后,通过inputStream读取数据:InputStream inputStream=socket.getInputStream()
4、关闭ServiceSoket:mServiceSocket.close()
客户端:
1、创建一个Socket对象,指定服务器的地址和端口号:Socket socket=new Socket(“172.168.10.2”,8080)
2、创建一个inputStream读取要发送的文件:InputStream inputStream=new FileInputStream(“e://a.txt”)
3、获取Socket的OutputStream对象用于发送数据:OutputStream outputStream=socket.getOutputStream()
4、把数据写入到OutputStream对象中:outputStream.write();
5、发送读取的数据到服务端:outputSteam.flush()基于UDP协议的数据传输服务端接收客户端实现://端口号可以在一个范围内自己定义,表示这个 DatagramSocket 在此端口上监听数据
1、创建一个DatagramSocket对象,并且指定端口号:DatagramSocket socket=new DatagramSocket(8080)
2、创建一个DatagramPacket对象,并指定DatagramPacket对象的大小:DatagramPacket packet=new DatagramPacket(data,data.length)
3、使用DatagramSocket的对象的receive接收数据:socket.recrive(packet)
4、将客户端发送的数据转换成字符串服务端发送数据实现:
1、创建DatagramSocket,指定端口号:DatagramSocket socket=new DatagramSocket(8080)
2、定义客户端地址:InetAddress address=packet.getAddress()//packet是上面服务端接收客户端实现步骤2的packet
3、定义客户端端口号:
int port=packet.getPort();//packet是上面服务端接收客户端实现步骤2的packet创建DatagramPacket,指定响应数据、数据的长度、客户端地址和客户端端口号:DatagramPacket packet2=new DatagramPacket(data2,data2.length,address,port)
4.通过DatagramSocket.send()方法发送数据:socket.send(packet2)
5.关闭资源:socket.close()
客户端发送数据实现:
1、创建一个DatagramSocket对象,指定监听的端口号:DatagramSocket socket=new DatagramSocket(8088)
2、使用InetAddress.getByName把IP地址转换成网络地址:
InetAddress serviceAddress=InetAddress.getByName(10.0.0.12)
3、创建一个DatagramPacket对象,用于发送数据: DatagramePacket packet=new DatagramPacket(data(要发送的数据),data.length(数据长度),serviceAddress(服务端的网络地址),8080(服务端端口号))
4、使用DatagramSocket.send发送数据到服务端:socket.send(packet)
客户端接收服务器返回的数据:
1、创建一个DatagramSocket,指定端口号,要和发送时的socket一致:DatagramSocket socket=new DatagramSocket(8088)
2、创建一个DatagramPacket packet=new DatagramSocket(data,data.length)
3、使用DatagramSocket.receive接收数据:socket.receive()
4、关闭DatagramSocket:socket.close()
44、Andorid系统架构(从上到下)应用程序层:用Java语言来编写应用程序框架层:从事Android开发的基础,开发人员可直接使用其提供的组件来进行快速的应用程序开发。系统运行库层:C++/C库以及Android运行库Linux内核层:
45、Binder机制原理从机制、模型角度来说:跨进程通信方式,实现了IBinder接口从模型结构、组成来说:Binder驱动:连接Service进程、Client进程和ServiceManager的桥梁从Andorid代码的实现角度来说:Binder机制具体实现原理:注册服务->获取服务->使用服务
46、Android如何加载大图片?对图片进行压缩针对图片的宽高进行压缩:首先获取加载图片的属性(BitmapFactory.Options、BitmapFactory.decodeResource),然后再缩小图片的长宽来压缩图片针对图片像素进行压缩,导致图片质量下降使用Fresco(Fresco是facebook推出的开源项目,该项目主要用来解决Android图片加载的)SimpleDraweeView或ZoomableView
47、LinearLayout(纵只能横用,横只能纵用)的gravity,layout_gravity和weight:gravity:view本身内容的位置layout_gravity:控制自己在父元素的位置weight:置该属性的控件的layout_width=“warp_content”,很正确.置该属性的控件的layout_width=“match_parent”,不正确.使用weight权重时,建议将width或height设置为0dp
48、Activity A 跳转到Activity B,生命周期的执行过程先是ActivityA的onpause()->ActivityB的onCreate()->ActivityB的onStart()->ActivityB的onResume()->ActivityA的onStop()
49、Android中Handler声明非静态对象会发出警告,为什么,非得是静态的?如果不使用static生命,则会导致内存泄漏。Handler被声明为一个非静态内部类或者匿名类可能会阻止外部类的垃圾回收
50、广播注册后不解除注册会有什么问题?
会出现内存泄漏
51、Dagger通过编译时注解方式,帮我们自动生成创建对象的工厂类。
52、在实际Android项目中用到的设计模式适配器模式:RecycleView与Adapter工厂模式:BitmapFactory观察者模式:EventBus、各种监听器、单例模式:ActivityManager、FragmentManager
53、单线程中Message、MessageQueue、Looper、Handler之间的关系。
通过Handler获取当前线程中的looper对象,发送消息Message:线程间交流的信息MessageQueue:用来存放Handler发布的MessageLooper:执行Message循环54、Android性能优化布局优化:减少布局的层级数,删除无用的控件和层级、采用标签、标签和ViewStub绘制优化:在view的onDraw中避免大量的操作,比如创建新的局部变量、做耗时操作内存泄漏优化:
(1)静态变量导致的内存泄漏:释放内存。
(2)属性动画导致的内存泄漏:在onDestroy中调用animator.cancel()来停止动画。响应速度优化:避免在主线程中做耗时操作,通过分析data/anr目录下的traces.txt文件定位出ANR原因(ANR日志分析)
ListView和Bitmap优化:
(1) listview采用ViewHolder并避免在getView中执行耗时操作,通过列表的滑动状态来控制任务的执行频率。(2) Bitmap主要通过BitmapFactory.Options来根据需要对图片进行采样线程优化:采用线程池,避免程序中存在大量的Thread
54、Rxjava作用:实现异步调用数据结构
1、链表:线性数据集合,用于表示顺序的数据结构分为单链表、双链表、循环链表
单链表:每一个节点只指向下一个节点,最后一个指向空
双链表:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点,最后一个指向null循环链表:每个节点指向下一个节点,最后一个节点指向第一个节点
2、栈:元素集合,支持两个基本操作:push用于将元素压入栈,pop用于删除栈顶元素后进先出的数据结构,索引和查找的时间复杂度是O(n),插入和删除的时间复杂度是O(1)
3、队列:元素集合,支持两个基本操作:enqueue用于添加一个元素到队列,dequeue用于删除队列的一个元素先进先出的数据结构,时间复杂度是索引和查找是O(n),插入和删除是O(1)
4、二叉树:树形数据结构,每个节点最多可以有左右两个子节点满二叉树:二叉树中的每个节点有0或2个子节点完美二叉树:二叉树中的每个节点有两个子节点,且所有的叶子结点的深度都一样完全二叉树:二叉树除了最后一层外其他各层的节点数均达到最大值,最后一层的节点都连续集中在最左边二叉查找数:任何节点的值都大于等于左子树的值,小于等于右子数的值
5、堆:基于树的满足某些特性的数据结构,分为最大堆和最小堆。在最大堆中,父节点的键值永远大于等于所有子节点的键值,根节点的键值最大。在最小堆中,父节点的键值永远小于等于所有子节点的键值,根节点的键值是最小的。
6、哈希:用于将任意长度的数据映射到固定长度的数据。