Activity之间数据传递与共享的几种途径(bitmap篇)&异步加载&service
来源:互联网 发布:ios性能优化 编辑:程序博客网 时间:2024/05/17 21:07
数据类型有限,比如遇到不可序列化的数据Bitmap,InputStream, 或者LinkList链表等等数据类型就不太好用。
2. 利用static静态数据, public static成员变量;
3.基于外部存储的传输, File/Preference/ Sqlite ,如果要针对第三方应用需要Content Provider
4.基于IPC的通信机制
context 与Service之间的传输,如Activity与Service之间的通信,定义AIDL接口文件。
示例: http://www.eoeandroid.com/thread-36249-1-1.html
5. 基于Application Context, 例子如下文:
在当前Activity将两个值传到了Test中。但如果遇到不可序列化的数据,如Bitmap、InputStream等,intent就无能为力了。因此,我们很自然地会想到另外一种方法,静态变量。如下面的代码所示:
public
class
Product
extends
Activity
{
public
static
Bitmap mBitmap;
}
对于上面的代码来说,其他任何类可以直接使用Product中的mBitmap变量。这么做很easy、也很cool,但却very very wrong。我们千万不要以为Davlik虚拟机的垃圾回收器会帮助我们回收不需要的内存垃圾。事实上,回收器并不可靠,尤其是手机上,是更加的不可靠。 因此,除非我们要使自己的程序变得越来越糟糕,否则尽量远离static。
注:如果经常使用static的Bitmap、Drawable等变量。可能就会抛出一个在Android系统中非常著名的异常(以前budget这个单词一直记不住什么意思,自从经常抛出这个异常后,这个单词终于烂熟于心了, )
ERROR/AndroidRuntime(4958): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
如果不使用static,总得有方法来代替它(尽管我很喜欢public static,我相信很多人也喜欢它,但为了我们的程序,建议还是忍痛割爱吧),那么这个新的解决方案就是本文的主题,这就是Application Context,相当于Web程序的Application,它的生命周期和应用程序一样长(这个我喜欢)。
那么现在来看看如何使用这个Application Context。我们可以通过Context.getApplicationContext或Context.getApplication方法获得 Application Context。但要注意,我们获得的只是Context对象,而更理想的方法是获得一个类的对象。ok,说干就干,下面来定义一个类。
package
net.blogjava.mobile1;
import
android.app.Application;
import
android.graphics.Bitmap;
public
class
MyApp
extends
Application
{
private
Bitmap mBitmap;
public
Bitmap getBitmap()
{
return
mBitmap;
}
public
void
setBitmap(Bitmap bitmap)
{
this
.mBitmap = bitmap;
}
}
上面这个类和普通的类没什么本质的不同。但该类是Application的子类。对了,这就是使用Application Context的第一步,定义一个继承自Application的类。然后呢,就在这个类中定义任何我们想使其全局存在的变量了,如本例中的 Bitmap。下面还需要一个重要的步骤,就是在<application>标签中使用android:name属性来指定这个类,代码如 下:
< application android:name =
".MyApp"
android:icon =
"@drawable/icon"
android:label =
"@string/app_name"
>
</ application>
接下来的最后一步就是向MyApp对象中存入Bitmap对象,或从MyApp对象中取出Bitmap对象了,存入Bitmap对象的代码如下:
MyApp myApp = (MyApp)getApplication();
Bitmap bitmap = BitmapFactory.decodeResource(
this
.getResources(), R.drawable.icon);
myApp.setBitmap(bitmap);
获得Bitmap对象的代码:
ImageView imageview = (ImageView)findViewById(R.id.ivImageView);
MyApp myApp = (MyApp)getApplication();
imageview.setImageBitmap(myApp.getBitmap());
上面两段代码可以在任何的Service、Activity中使用。全局的。
技术一、异步下载资源,实现时时更新进度或者相关百分比
第一种:可能大部分人在学习android的时候,都会自主用线程池另开辟一条后台线程,或者直接新启一条线程,。这里和android四大组件之一的Service并不相冲突。下载的时候毕竟还是线程方法体内执行的,即使是Service可能还要做些其他事,并一定让它处于阻塞状态,废话有点多。。
这里简单的说下线程+handler整体实现:
在继承的Activity的类中,直接开辟一条新的线程,由此线程完成下载任务,当然更新进度条是由android.os下面提供的handler,这是比较不错的跨线程操作的类..
public class FileDownloadDemo extends Activity {
private ProgressBar downloadProgressBar;
private Button downloadBt;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
downloadBt.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//这里开辟一个线程,不多说
。。。
}
});
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//...这里设置downloadProgressBar的Progress值,用setProgress方法
}
};
class downloadTask extends Thread {
@Override
public void run() {
//这里执行下载等操作
......
// 通知handler去更新视图组件
handler.sendEmptyMessage(0);
// 休息1秒后再读取下载进度
sleep(1000);
}
}
整体是这么一个样子,这里给出整体源文件,供大家参考
MoreThreadDowns.zip
第二种:Android的os包下还提供了一种集成handler的类,使用起来代码量相对少很多,理解相对就麻烦点,但也不是太难。。
AsyncTask 这个类一看就是和异步操作有关系的
只要写一个类去继承AsyncTask,重写某些方法就可以实现异步效果,并时时更新进度条。。。
Activity中调用这个类,只需要传入你需要时时改变的Widget控件就可以了
public class PageTask extends AsyncTask<String, Integer, String> {
private TextView message;
private ProgressBar progressBar;
public PageTask(TextView message, ProgressBar progressBar) {
super();
this.message = message;
this.progressBar = progressBar;
}
//可变长的输入参数,与AsyncTask.exucute()对应
@Override
protected String doInBackground(String... params) {
System.out.println("doInBackground...");
int i=0;
for( i=10;i<101;i+=10){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return i+"";
}
@Override
protected void onCancelled() {
System.out.println("onCancelled...");
super.onCancelled();
}
@Override
protected void onPostExecute(String result) {
//返回HTML页面的内容
System.out.println("onPostExecute:"+result);
message.setText(result);
}
@Override
protected void onPreExecute() {
//任务启动,可以在这里显示一个对话框,这里简单处理
System.out.println("onPreExecute...");
message.setText(R.string.task_started);
}
@Override
protected void onProgressUpdate(Integer... values) {
//更新进度
System.out.println("onProgressUpdate...");
progressBar.setProgress(values[0]);
}
这里给出例子。。代码少很多哦
AsyncTaskDemo.zip
一个例子让你懂得service的各种玄机
首先呢 我们要创建一个MyService,让其继承Service.然后实现其中的重要的方法,代码如下:
public class MService extends Service {
@Override
public IBinder onBind(Intent arg0) {
System.out.println("onBind");
return new MyBinder();
}
public void sayHelloInService() {
System.out.println("hello in service");
}
@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}
@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
System.out.println("onStart");
super.onStart(intent, startId);
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("onUnbind");
return super.onUnbind(intent);
}
public class MyBinder extends Binder implements IService {
@Override
public void callMethodInService() {
sayHelloInService();
}
}
这样,service的基本功能就已经实现了,下面我们看一下Activity中的代码:
public class MainActivity extends Activity implements OnClickListener {
Button btn_start;
Button btn_stop;
Button btn_bind;
Button btn_unbind;
Button btn_call_service;
Intent intent;
MyServiceConn conn;
MyBinder Iservice;
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn_start = (Button) this.findViewById(R.id.btn1);
btn_stop = (Button) this.findViewById(R.id.btn2);
btn_bind = (Button) this.findViewById(R.id.btn3);
btn_unbind = (Button) this.findViewById(R.id.btn4);
btn_call_service = (Button) this.findViewById(R.id.btn5);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
btn_bind.setOnClickListener(this);
btn_unbind.setOnClickListener(this);
btn_call_service.setOnClickListener(this);
intent=new Intent(this,MService.class);
conn=new MyServiceConn();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn1:
startService(intent);
break;
case R.id.btn2:
stopService(intent);
break;
case R.id.btn3:
bindService(intent, conn, BIND_AUTO_CREATE);
break;
case R.id.btn4:
unbindService(conn);
break;
case R.id.btn5:
Iservice.callMethodInService();
break;
}
}
private class MyServiceConn implements ServiceConnection{
/**
* 从service里返回的两个参数
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Iservice=(MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
通过按钮的事件监听,就可以让Activity跟service间互动了。例子中也体现出了startservice()和bindservice()之间的区别,希望对各位有用。
- Activity之间数据传递与共享的几种途径(bitmap篇)&异步加载&service
- Activity之间数据传递与共享的几种途径-- bitmap篇
- Activity之间数据传递与共享的几种途径(bitmap篇)
- android 应用程序Activity之间数据传递与共享的几种途径
- android 应用程序Activity之间数据传递与共享的几种途径
- android 应用程序Activity之间数据传递与共享的几种途径
- android 应用程序Activity之间数据传递与共享的几种途径
- android 应用程序Activity之间数据传递与共享的几种途径(转)
- android 应用程序Activity之间数据传递与共享的几种途径
- android 应用程序Activity之间数据传递与共享的几种途径(1)
- android 应用程序Activity之间数据传递与共享的几种途径(2)
- android 应用程序Activity之间数据传递与共享的几种途径
- android 应用程序Activity之间数据传递与共享的几种途径
- Android 应用程序Activity之间数据传递与共享的几种途径你知道吗
- Service与Activity之间的数据传递
- Activity之间的数据传递-service与activity之间的数据传递
- android 中Service 和activity之间的数据传递的几种方法
- android 中Service 和activity之间的数据传递的几种方法
- 设置TextBox中只能输入数字
- HDU1584(分治法)
- php资料
- Subversion安装配置(Windows)之详解(1)
- Linux 下软件安装方法总结
- Activity之间数据传递与共享的几种途径(bitmap篇)&异步加载&service
- __attribute__
- Linux 下软件安装详解
- c# JsonHelper 帮助类
- C / C++算法学习笔记(7)-双向冒泡
- Subversion安装配置(Windows)之详解(2)
- CodeForce Round #186 Div.2
- obj-c iOS 开发,取得当前目录下后缀名这.png的文件目录。
- uboot命令