Xutils 分为四大板块: DbUtils, HttpUtils,BitmapUtils ,ViewUtils,
**********************
在内存中进行操作获取内部存储data:data;命令: Openfileoutput(); openfileinput;
创建暂时存储:File.creatTempFile(;;;);
1.获得SD卡是否是只读的:boolean equals = Environment.getExternalStorageState().equals(Environment .MEDIA_MOUNTED_READ_ONLY);
****************
访问Android SD目录下的:music: Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);怎么把在控制台输入的文字保存到文件中:文件标准路径:File f = new File("D:"+File.separator+"abc"+File.separator+"123.txt");File externalFilesDir = getExternalFilesDir(null);//SD卡下的私有文件夹:
3.在A服务没有销毁的情况下 ,不能被重新创建。(只执行onstartcommend,不执行 oncreat);FileOutputStream fileOutputStream = new FileOutputStream(externalFilesDir + "/lfk.txt"); PrintStream printStream = new PrintStream(fileOutputStream); printStream.print("kk,is a good man"); printStream.close(); fileOutputStream.close();******************2.简单的实现了刷新数据,listview在SwipRefreshLayout内部;Listview.addheadview 或者addfootview要在.setadapter之前。<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swp" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ListView android:id="@+id/lv_main" android:layout_width="match_parent" android:layout_height="match_parent">ListView> 然后在重写的监听事件里:*****************setOnRefreshListener:添加:mSwipe.setRefreshing(false);//来代表加载完成,消失圆圈,
android.support.v4.widget.SwipeRefreshLayout>
stopservice---onDestory();
服务不能自己运行,需要通过调 用 Context.startService() 或 Context.bindService() 方法启动服务。
【注意:服务的生命周期方法都是在主线程执行,所以不能直接在服务里面做耗时操作做,如果需要做耗时操作,应该在服务里面开启子线程。】
****************************
5.使用数据库的基本套路:创建一个DateBaseHelp 然后继承SqlopenHelper,重写方法。然后创建一个操作数据的类:DbAdapter:然后添加增删改查的方法,前提是调用之前创建的DateBseHelp;
//Uri.parse(path)----将字符串转化成有效的内存地址。
//创建表的语句:创建: public static final String CREAT ="create table dog(_id integer primary key autoincrement," + "name text,age integer)";删除表单: public static final String DROP_TABLE_DOG = "drop table if exists dog";如果只想删除此表单全部数据"delete from dog";
http://note.youdao.com/share/?id=1f6c7cbb2e4d4670f5d796f71995fb02&type=note.
**************
5.创建一个notification的套路:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("国庆节快乐"); builder.setContentTitle("还好新消息"); builder.setDefaults(Notification.DEFAULT_SOUND); Intent i = new Intent(this,Main2Activity.class); Intent[]i2 = new Intent[]{i}; i.setClass(this,Main2Activity.class); //上下文 请求编码 意图 PendingIntent pi = PendingIntent.getActivities(this,2,i2,PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(pi);//设置点击通知的事件:比如跳转;阅读等等; builder.setSmallIcon(R.mipmap.ic_launcher).setTicker("新消息"); NotificationManager systemService = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); systemService.notify(1,builder.build());****************
Listview嵌套 Girdview 并且要求显示Girdview的全部信息:
解决办法:
重写GridView:
public class MyGridView extends GridView { public MyGridView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyGridView(Context context, AttributeSet attrs) { super(context, attrs); } public MyGridView(Context context) { super(context); } /** * 设置不滚动 */ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
然后在item的xml布局中使用:
******************
!!!sharepreference的简单用法:
public void save(View v){ String username = et_username.getText().toString();//获取用户名 String phone = et_phone.getText().toString();//获取用户名 if(TextUtils.isEmpty(username)){ Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); return; } if(TextUtils.isEmpty(phone)){ Toast.makeText(this, "手机号不能为空", Toast.LENGTH_SHORT).show(); return; } //使用SharedPreferences //getSharedPreferences() 第一个参数是文件名 // MODE_PRIVATE 不允许其他应用程序读写user.xml文件 SharedPreferences sp = getSharedPreferences("user", MODE_PRIVATE); //获取SharedPreferences的对象 //通过edit()获取一个编辑器 Editor et = sp.edit(); //使用key-value的方式存储数据 et.putString("username", username); et.putString("phone", phone); et.putInt("age", 30); //提交生效 et.commit(); } *******************Broastreciver:
手机开机的时候会发送一条开机广播:
用应用给好友发一条信息:
public void sendms(View v){ SmsManager aDefault = SmsManager.getDefault();//获取信息管理者 String msm = "你好,我是你大爷!";//短信内容 ArrayList发射闹钟:list = aDefault.divideMessage(msm);//拆分短信 System.out.print(list.size()+"我终于输出了"); for (int i = 0; i "1567088****",null,list.get(i),null,null); } }
*******************************
2、Service 与 Thread 的区别
很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来解释一下。
1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。
2). Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。因此请不要把 Service 理解成线程,它跟线程半毛钱的关系都没有!
既然这样,那么我们为什么要用 Service 呢?其实这跟 android 的系统机制有关,我们先拿 Thread 来说。Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。
举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。
因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。
******************
关于Girdview的设置问题:
<GridView android:id="@+id/gv_main" android:horizontalSpacing="9sp"//水平间距 android:verticalSpacing="9sp"//垂直间距(注意这里用的是sp dp估计不能生效)。 android:layout_width="match_parent" android:layout_height="match_parent" android:numColumns="2" />关于数据重新加载的问题:每当数据源发生改变时 指针条目(当前所指向的条目会跳到第一个解决问题的办法是:)int canse=10;
m.setItems(items); gvMain.setAdapter(m); m.notifyDataSetChanged();这样就可以在数据源发生改变以后 指针还会指到当前的条目上 而不会重新回到第一个布局。gvMain.setSelection(cansee);//setSelection:设置当前说在的条目id上(id是累加的)。 cansee+=20;
*******************************************************************************
一.service(服务)
启动一个服务:starservice开启一个服务。
onstartcomment:开始执行命令。
当启动一个已经被启动的服务会直接执行onstartcomment()这个方法不会执行oncreat();
1.默认情况下服务和主线程在同一个线程中,如果服务执行一个比较耗时的操作,那么就要使用一个子线程来完成
耗时操作,避免阻塞主线程。
onstartcomment()方法的返回值有四种不同的值:
1.START_STICKY:如果service被kill掉,尝试着重新启动。但是Intent值已经被清空。(默认返回值)。
2.START_NO_STICKY:非粘性的 如果服务被异常kill掉,系统不会自动重启该服务。
3.START_REDELIVER_INTENT:重传intent:服务被kill掉,重新启动该服务。(是异常kill不是正常kill)。
2.Intentservice:当任务完成后自动会停止,不用手动去停止。而且不用自己去创建线程。自己本身自带线程。
只用实现:onHandleIntent(Intent intent);
同时执行多个耗时任务时,会以工作队列的方式,依次执行。
3.Bind Service:
轮询:每隔一段时间发送一个广播。
Timer tr = new Timer();用来执行轮询的
seekbar(progressbar的升级版)可以手动拖拽。
.setprogress(当前进度),.setMax(设置最大的进度值)。
IPC进程间的通信。**************************************
自定义view组件:
继承布局:继承ViewGroup或者其子Layout类布局类组合。
继承View的子类具体类。
****************************广播
LocalBroadcastManager是Android Support包提供了一个工具,是用来在同一个应用内的不同组件间发送Broadcast的。
使用LocalBroadcastManager有如下好处:
1 @Override
2 public boolean onKeyDown(int keyCode, KeyEvent event) {
3 // TODO Auto-generated method stub
4
5 if(keyCode==KeyEvent.KEYCODE_BACK){
6 //弹出确定退出对话框
7 new AlertDialog.Builder(this)
8 .setTitle("退出")
9 .setMessage("确定退出吗?")
10 .setPositiveButton("确定", new DialogInterface.OnClickListener() {
11
12 @Override
13 public void onClick(DialogInterface dialog, int which) {
14 // TODO Auto-generated method stub
15 Intent exit = new Intent(Intent.ACTION_MAIN);
16 exit.addCategory(Intent.CATEGORY_HOME);
17 exit.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
18 startActivity(exit);
19 System.exit(0);
20 }
21 })
22 .setNegativeButton("取消", new DialogInterface.OnClickListener() {
23
24 @Override
25 public void onClick(DialogInterface dialog, int which) {
26 // TODO Auto-generated method stub
27 dialog.cancel();
28 }
29 })
30 .show();
31 //这里不需要执行父类的点击事件,所以直接return
32 return true;
33 }
34 //继续执行父类的其他点击事件
35 return super.onKeyDown(keyCode, event);
36 }
*******************第二种按键返回:
private long exitTime = 0;
public void ExitApp() { if ((System.currentTimeMillis() - exitTime) > 2000) { Toast.makeText(this.activity, "再按一次退出程序", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else { this.activity.finish(); }
}
map = bmapView.getMap();//获取地图, map.setMapType(BaiduMap.MAP_TYPE_NORMAL);//普通地图 map.setMapType(BaiduMap.MAP_TYPE_SATELLITE);//卫星地图 map.setTrafficEnabled(true);//实时交通图。//红色表示拥堵。黄:轻度:绿:正常。 LatLng latLng = new LatLng(39.963175,116.400244);//经纬度。 BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(android.R.drawable.ic_input_get); OverlayOptions options = new MarkerOptions().position(latLng).icon(bitmapDescriptor); map.addOverlay(options);//把选项添加到地图
//旋转360度。 ObjectAnimator.ofFloat(view,"rotationY",0.0f,360f).setDuration(1000).start();//组合多个动画在一起:
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("alpha",1f,0,1f); PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("scaleX",1f,0,1f); PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("scaleY",1f,0,1f); ObjectAnimator.ofPropertyValuesHolder(view,p1,p2,p3);(view表示作用的控件)。
监听动画时间:通过Viewpageindactor对viewpage添加属性:ObjectAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", 1, 0).setDuration(1000); alpha.start(); alpha.addListener(new Animator.AnimatorListener() {****;//监听事件。AnimatorSet animatorSet = new AnimatorSet();//动画集:若干个动画一并执行、 animatorSet.playTogether();
alpha.setInterpolator(new AccelerateDecelerateInterpolator());//反弹效果。****************使用第三方框架制作圆形头像:
添加依赖:build.gradle:compile 'de.hdodenhof:circleimageview:2.1.0'
<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/profile_image" android:layout_width="96dp"//设置圆形大小 长宽一致。 android:layout_height="96dp" android:src="@drawable/tt" app:civ_border_width="2dp"//设置边框宽度 app:civ_border_color="#90cccccc"/>//设置边框颜色Ormlite********************通过操作对象来达到对数据库操作的目的。
<android.support.v4.view.ViewPager android:id="@+id/vp_main" android:layout_width="match_parent" android:layout_height="match_parent"> android.support.v4.view.ViewPager> <com.viewpagerindicator.CirclePageIndicator//用来添加指示器 android:layout_marginTop="50dp" android:id="@+id/indicatorcc" android:padding="10dip" android:layout_height="wrap_content" android:layout_width="fill_parent" android:background="#FFCCCCCC" app:radius="10dp" app:fillColor="#fff" app:pageColor="#88FF0000" app:strokeColor="#FF000000" app:strokeWidth="2dp" />
String s = "#ff0000";//用字符串表示的颜色。 tvMain2.setTextColor(Color.parseColor(s));//用来将字符串表示的的颜色转化成int类型、*******************************设置文字在一行显示多余的用省略号表示。
话不多说,看红色部分,width属性必须要设才有作用:
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/PopNameList"
android:singleLine="true"
android:ellipsize="end"
android:textStyle="bold"
android:textSize="15sp"
android:width="120dp" />**************************实现无线轮播功能:
添加依赖:
dependencies{ compile 'com.youth.banner:banner:1.4.1' //最新版本 }还要一个重要的框架:compile 'com.android.support:appcompat-v7:24.1.1'//这个不用添加 compile 'com.github.bumptech.glide:glide:3.6.0'xml:
<com.youth.banner.Banner android:id="@+id/baner" xmlns:app="http://schemas.android.com/apk/res-auto" app:indicator_width="8dp"app:title_background="#9000ff00"//标题栏背景颜色 app:title_height="50dp"//标题栏高度app:title_textcolor="#00ffff"//标题字体颜色 app:title_textsize="20sp"//字体大小app:indicator_drawable_selected="@drawable/up"//选中时显示 app:indicator_drawable_unselected="@drawable/mark"//没选中时候显示 app:indicator_height="15dp"//指示器高度 app:indicator_margin="15dp" android:layout_width="match_parent" android:layout_height="250dp" >com.youth.banner.Banner>
更多详情:https://github.com/youth5201314/banner/blob/master/README.md
ArrayLists = new ArrayList<>();//用来存储图片网址的集合: s.add("http://img2.3lian.com/2014/f2/37/d/39.jpg"); s.add("http://img2.3lian.com/2014/f2/37/d/40.jpg"); baner.setImages(s).setImageLoader(new GlideImageLoader()); baner.isAutoPlay(true);
baner.setBannerStyle(3);//设置样式baner.start(); } private void initView() { activityMain2 = (LinearLayout) findViewById(R.id.activity_main2); baner = (Banner) findViewById(R.id.baner); } public class GlideImageLoader implements ImageLoader { @Override public void displayImage(Context context, Object path, ImageView imageView) { Glide.with(context).load(path).into(imageView); } }}
<LinearLayout android:orientation="vertical" android:id="@+id/ll" android:layout_width="wrap_content" android:layout_height="wrap_content"> LinearLayout>
TextView tv = new TextView(this); tv.setText("我我哦哦我我"); tv.setHeight(200); tv.setWidth(200); tv.setBackgroundColor(Color.BLUE); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);//定义一个LayoutParams layoutParams.setMargins(100,0,100,100); tv.setLayoutParams(layoutParams); TextView tv2 = new TextView(this); tv2.setText("cccccccccc"); tv2.setHeight(400); tv2.setWidth(400); tv2.setBackgroundColor(Color.RED); ll.addView(tv); ll.addView(tv2);//来实现动态的准确宽高 以及控件之间的间距;但是要注意的是Linlaout必须是wrap_conten,不然设置失效。
************************xutils3的使用:对xutils进行初始化(可以创建一个application然后初始化)关于xutils3的使用的详细信息(包括网络请求,和数据库的操作等);SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);//获得系统服务的传感器管理者ListallSensors = sm.getSensorList(Sensor.TYPE_ALL);//获得全部的传感器的列表 //在这里通过点击一个Button按钮来触发光亮传感器服务public void lightSensors(View view) { Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_LIGHT); sm.registerListener(LightListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); } // 光照传感器的事件 private SensorEventListener LightListener = new SensorEventListener(){ @Override public void onSensorChanged(SensorEvent event) { float value = event.values[0]; Sensor sensor = event.sensor; textView.setText(value + ""); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { Log.i(TAG, "on accuracy change: " + accuracy); } };//开启一个声音池:new SoundPool(5, AudioManager.STREAM_MUSIC, 0);//第一个参数是声音流的最大数目,第二个参数为声音流的类型,第三个参数为 采样率转化质量。//急速传感器的设置:
private SensorEventListener AcclerListener = new SensorEventListener() {//加速传感器的监听事件, @Override public void onSensorChanged(SensorEvent event) { // 加速度可能会是负值,所以要取它们的绝对值 float xValue = Math.abs(event.values[0]);//在x轴上加速度(下面依次类推) float yValue = Math.abs(event.values[1]); float zValue = Math.abs(event.values[2]); if (xValue > 15 || yValue > 15 || zValue > 15) { // 认为用户摇动了手机,触发摇一摇逻辑 Toast.makeText(MainActivity.this, "摇一摇", Toast.LENGTH_SHORT).show(); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { Log.i(TAG, "on accuracy change: " + accuracy); } };mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);//获取系统的震动服务(摇一摇的时候会触发震动事件;*********************************
MotionEvent对象是与用户触摸相关的时间序列,该序列从用户首次触摸屏幕开始,经历手指在屏幕表面的任何移动,直到手指离开屏幕时结束。手指的初次触摸(ACTION_DOWN操作),滑动(ACTION_MOVE操作)和抬起(ACTION_UP)都会创建MotionEvent对象。所以每次触摸时候这三个操作是肯定发生的,而在移动过程中会产生大量事件,每个事件都会产生对应的MotionEvent对象记录发生的操作,触摸的位置,使用的多大压力,触摸的面积,合适发生,以及最初的ACTION_DOWN和时发生等相关的信息。
***************************使用Ormitesql进行数据库操作:D:\feiqiu\feiq\Recv Files\feiq\AutoRecv Files\李张亮(002186A1AF2E)(记得导jar):ORMlite通过Java注解的方式来建立起与数据库的映射关系
****************D:\feiqiu\feiq\Recv Files\feiq\AutoRecv Files\李张亮(002186A1AF2E)\swip_active\activeandroid\src\main\java\com\qianfeng\activeandroid\modle//另一种数据库操作的书写方法。
D:\feiqiu\feiq\Recv Files\feiq\AutoRecv Files\李张亮(002186A1AF2E)\swip_active\app\src\main\java\com\qianfeng\swip_active//用来创建侧滑listview(添加菜单等功能)。
//设置窗体始终点亮
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
//设置窗体背景模糊
getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
2.内部解析:目的(子线程中下载图片,下载完成之后通知主线程更新ui)
1.主线程中有一个消息处理器Handle,被放在主线程中的消息队列中
2.在主线程中有一个MessageQueue 也就是消息队列,存放消息
3.在主线程中也有一个Looper (不停的循环消息队列取消息)如果有新的消息就将消息交给消息处理器,handle会调用其中的handleMessage处理消息
3.具体实施
1.子线程,利用handle发送消息放在主线程的消息队列中
2.主线程里面有一个looper循环获取消息
3.发现新的消息,就会调用handlemessage方法处理消息
Service随着启动形式的不同,其生命周期稍有差别。当用Context.startService()来启动时,Service的生命周期依次为:oncreate——>onStartCommand——>onDestroy 当用Context.bindService()启动时:onStart——>onBind——>onUnbind——>onDestroy。 Service启动方式有两种;一是Context.startService和Context.bindService。 区别是通过startService启动时Service组件和应用程序没多大的联系;当用访问者启动之后,如果访问者不主动关闭,Service就不会关闭,Service组件之间因为没什么关联,所以Service也不能和应用程序进行数据交互。而通过bindService进行绑定时,应用程序可以通过ServiceConnection进行数据交互。 在实现Service时重写的onBind方法中,其返回的对象会传给ServiceConnection对象的onServiceConnected(ComponentName name, IBinder service)中的service参数;也就是说获取了serivce这个参数就得到了Serivce组件返回的值。Context.bindService(Intent intent,ServiceConnection conn,int flag)其中只要与Service连接成功conn就会调用其onServiceConnected方法,停用Service使用Context.stopService。**************************两种注册广播的方式,以及两者之间的区别,优缺点:
首先写一个类要继承BroadcastReceiver
第一种:在清单文件中声明,添加
第二种使用代码进行注册如: IntentFilterfilter = newIntentFilter("android.provider.Telephony.SMS_RECEIVED"); IncomingSMSReceiverreceiver = new IncomgSMSReceiver(); registerReceiver(receiver.filter); 两种注册类型的区别是: 1)第一种是常驻型(静态注册),也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。 2)第二种不是常驻型广播(动态注册),也就是说广播跟随程序的生命周期。 注册的方法有两种,一种是静态注册,一种是动态注册。 动态注册优点:在 Android 的广播机制中,动态注册的优先级是要高于静态注册优先级的,因此在必要的情况下,我们是需要动态注册广播接收器的。
AndroidManifest.xml 是每个android程序中必须的文件。它位于整个项目的根目录,描述了package中暴露的组件(activities, services, 等等),他们各自的实现类,各种能被处理的数据和启动位置。 除了能声明程序中的Activities, ContentProviders, Services, 和Intent Receivers,还能指定permissions和instrumentation(安全控制和测试)
可以将XX.db文件复制到Eclipse Android工程中的res\raw目录中。所有在res\raw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。1.适用场景
1) ContentProvider为存储和读取数据提供了统一的接口
2) 使用ContentProvider,应用程序可以实现数据共享
3) Android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
2.相关概念介绍
1)ContentProvider简介
当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式
在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它们之间可以用来通信的方式就更多了,这样看来,广播机制似乎是多余的。然而,广播机制却是不可替代的,它和Binder机制不一样的地方在于,广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是,系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。 在软件工程中,是非常强调模块之间的高内聚低耦合性的,而且它根本上不依赖这个Activity或者Service的实现,只需要知道它的字符串形式的名字即可,而广播机制更绝,它连接收者的名字都不然的话,随着系统越来越庞大,就会面临着越来越难维护的风险,最后导致整个项目的失败。Android应用程序的组织方式,可以说是把这种高内聚低耦合性的思想贯彻得非常透彻,在任何一个Activity中,都可以使用一个简单的Intent,通过startActivity或者startService,就可以把另外一个Activity或者Service启动起来为它服务,不需要知道。
***********************在网络上加载一张图片
DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int widthPixels = dm.widthPixels; int heightPixels = dm.heightPixels;**********************************
*******************至于startservice和bindservice的使用场景,有网友这么说:
1.通过startservice开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了.
调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在
2.通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 ,
一旦调用者挂掉了.service也会跟着挂掉 .