Android service 生命周期 和 图片的缩放翻转功能

          Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service。Service 可以分为有无限生命和有限生命两种。
 特别需要注意的是Service跟Activities是不同的(简单来说可以理解为后台与前台的区别),例如,如果需要使用Service的话,
 需要调用startService(),从而利用startService()去调用Service中的OnCreate()和onStart()方法来启动一个后台的Service。

 Service的开发如下:
    1.创建继承自Service的类,并实现相关的方法。
    2.在androidmanifest.xml中application中添加service配置。
    3.通过intent启动或者关闭 相关的服务
  启动一个Service的过程如下:
  context.startService()  ->onCreate()- >onStart()->Service running
  其中onCreate()可以进行一些服务的初始化工作,onStart()则启动服务。
  
  
  停止一个Service的过程如下:
  context.stopService() | ->onDestroy() ->Service stop

    各种目录文件的获取资源信息:
 /res/xml:
    XmlResourceParser xml = getResources().getXml(R.xml.data);  

 
 /res/raw
    getResources().openRawResource(R.raw.rawtext)  
 
 
 /assets
        AssetManager assets = getAssets(); 
        assets.open("data.txt"))  

 

服务的生命周期

部分内容参考自CSDN博客:http://blog.csdn.net/wtao158/archive/2010/01/08/5149721.aspx

 

有了 Service 类我们如何启动他呢,有两种方法:

      • Context.startService()
      • Context.bindService()


     1.  在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。另外如果一个 Service 已经被启动,其他代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart() 。

      2. 另外一种 bindService() 方法的意思是,把这个 Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。

     

      总结:

      1. startService()的目的是回调onStart()方法,onCreate() 方法是在Service不存在的时候调用的,如果Service存在(例如之前调用了bindService,那么Service的onCreate方法已经调用了)那么startService()将跳过onCreate() 方法。

      2.  bindService()目的是回调onBind()方法,它的作用是在Service和调用者之间建立一个桥梁,并不负责更多的工作(例如一个Service需要连接服务器的操作),一般使用bindService来绑定到一个现有的Service(即通过StartService启动的服务)。

      由于Service 的onStart()方法只有在startService()启动Service的情况下才调用,故使用onStart()的时候要注意这点。

 

与 Service 通信并且让它持续运行

      如果我们想保持和 Service 的通信,又不想让 Service 随着 Activity 退出而退出呢?你可以先 startService() 然后再 bindService() 。当你不需要绑定的时候就执行 unbindService() 方法,执行这个方法只会触发 Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。

 

提高 Service 优先级

      Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。

      为什么是 foreground ? 默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。

 

摘自网络其他资料:关于Service生命周

Android Service生命周期与Activity生命周期是相似的,但是也存在一些细节上也存在着重要的不同:

onCreate和onStart是不同的

通过从客户端调用Context.startService(Intent)方法我们可以启动一个服务。如果这个服务还没有运行,Android将启动它并且在onCreate方法之后调用它的onStart方法。如果这个服务已经在运行,那么它的onStart方法将被新的Intent再次调用。所以对于单个运行的Service它的onStart方法被反复调用是完全可能的并且是很正常的。

onResume、onPause以及onStop是不需要的

回调一个服务通常是没有用户界面的,所以我们也就不需要onPause、onResume或者onStop方法了。无论何时一个运行中的Service它总是在后台运行。

onBind

如果一个客户端需要持久的连接到一个服务,那么他可以调用Context.bindService方法。如果这个服务没有运行方法将通过调用onCreate方法去创建这个服务但并不调用onStart方法来启动它。相反,onBind方法将被客户端的Intent调用,并且它返回一个IBind对象以便客户端稍后可以调用这个服务。同一服务被客户端同时启动和绑定是很正常的。

onDestroy

与Activity一样,当一个服务被结束是onDestroy方法将会被调用。当没有客户端启动或绑定到一个服务时Android将终结这个服务。与很多Activity时的情况一样,当内存很低的时候Android也可能会终结一个服务。如果这种情况发生,Android也可能在内存够用的时候尝试启动被终止的服务,所以你的服务必须为重启持久保存信息,并且最好在onStart方法内来做。

 

 

在android中Activity负责前台界面展示,service负责后台的需要长期运行的任务。Activity和Service之间的通信主要由IBinder负责。在需要和Service通信的Activity中实现ServiceConnection接口,并且实现其中的onServiceConnected和onServiceDisconnected方法。然后在这个Activity中还要通过如下代码绑定服务:

Java代码 
  1. Intent intent = new Intent().setClass( this , IHRService.class );  
  2. bindService( intent , this , Context.BIND_AUTO_CREATE );  

 当调用bindService方法后就会回调Activity的onServiceConnected,在这个方法中会向Activity中传递一个IBinder的实例,Acitity需要保存这个实例。代码如下:

Java代码 
  1. public void onServiceConnected( ComponentName inName , IBinder serviceBinder) {  
  2.     if ( inName.getShortClassName().endsWith( "IHRService" ) ) {  
  3.     try {  
  4.         this.serviceBinder= serviceBinder;  
  5.         mService = ( (IHRService.MyBinder) serviceBinder).getService();  
  6.         //mTracker = mService.mConfiguration.mTracker;  
  7.         } catch (Exception e) {}  
  8.               
  9.     }  
  10. }  

 

在Service中需要创建一个实现IBinder的内部类(这个内部类不一定在Service中实现,但必须在Service中创建它)。

Java代码 
  1. public class MyBinder extends Binder {  
  2. //此方法是为了可以在Acitity中获得服务的实例  
  3.     public IHRService getService() {  
  4.         return IHRService.this;  
  5.     }  
  6. //这个方法主要是接收Activity发向服务的消息,data为发送消息时向服务传入的对象,replay是由服务返回的对象  
  7.     public boolean onTransact( int code , Parcel data , Parcel reply , int flags ) {  
  8.         //called when client calls transact on returned Binder  
  9.         return handleTransactions( code , data , reply , flags );  
  10.     }  
  11.   
  12. }  

  

然后在Service中创建这个类的实例:

Java代码 
  1. public IBinder onBind( Intent intent ) {  
  2.     IBinder result = null;  
  3.     if ( null == result ) result = new MyBinder() ;  
  4.     return result;  
  5. }  

 这时候如果Activity向服务发送消息,就可以调用如下代码向服务端发送消息:

Java代码 
  1. inSend = Parcel.obtain();  
  2. serviceBinder.transact( inCode , inSend , null , IBinder.FLAG_ONEWAY );  

 

这种方式是只向服务端发送消息,没有返回值的。如果需要从服务端返回某些值则可用如下代码:

Java代码 
  1. result = Parcel.obtain();  
  2. serviceBinder.transact( inCode , inSend , result , 0 );  
  3. return result;  

发送消息后IBinder接口中的onTransact将会被调用。在服务中如果有结果返回(比如下载数据)则将结果写入到result参数中。在Activity中从result中读取服务执行的结果。

 

上面只是描述了如何由Acitity向Service发送消息,如果Service向Activity发送消息则可借助于BroadcastReceiver实现,BroadcastReceiver比较简单,前面在将Service中已有提及。

 

android service使用实例:

 

package com.etrip.srvs;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
 * 	

	
实例:	
	接下来的实例是一个利用后台服务播放音乐的小例子,点击start运行服务,点击stop停止服务。
 * 
 * 
 * @author longgangbai
 */
public class AndroidServicesActivity extends Activity implements OnClickListener {
	  private static final String TAG = "ServicesDemo";
	  Button buttonStart, buttonStop;

	  @Override
	  public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.main);

	    buttonStart = (Button) findViewById(R.id.buttonStart);
	    buttonStop = (Button) findViewById(R.id.buttonStop);

	    buttonStart.setOnClickListener(this);
	    buttonStop.setOnClickListener(this);
	  }

	  public void onClick(View src) {
	    switch (src.getId()) {
	    case R.id.buttonStart:
	      Log.d(TAG, "onClick: starting srvice");
	      startService(new Intent(this, MyService.class));
	      break;
	    case R.id.buttonStop:
	      Log.d(TAG, "onClick: stopping srvice");
	      stopService(new Intent(this, MyService.class));
	      break;
	    }
	  }
	}

 

 service的实现:

package com.etrip.srvs;


import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/**
 * 
 * Service的学习
 * 
 *  
 * @author longgangbai
 */
public class MyService extends Service {
	private static final String TAG = "MyService";
	MediaPlayer player;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	
	@Override
	public void onCreate() {
		Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onCreate");
		
		player = MediaPlayer.create(this, R.raw.baby);//运行例子是,需要替换音乐的名称
		player.setLooping(false); // Set looping
	}

	@Override
	public void onDestroy() {
		Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onDestroy");
		player.stop();
	}
	
	@Override
	public void onStart(Intent intent, int startid) {
		Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onStart");
		player.start();
	}
}

 

 

图片翻转:

package com.easyway.andorid.hello;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout.LayoutParams;

/**
 * Android实现图片的缩放功能
 * @author longgangbai
 * @date 2010-5-24
 * @version 1.0
 * @since JDK6.0
 */
public class ImageViewAndorid extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         //设置程序的标题
         setTitle("缩放和旋转图片");
         //实例化LinearLayout类的对象lly
         LinearLayout lly=new LinearLayout(this);
         //获取图片的信息 这里用的是icon.png ,图片存放的位置在res/drawable下,
         //同时这里还方有itfunz.bmp,这就是应用程序的图标
         Bitmap bmpOrg=BitmapFactory.decodeResource(getResources(), R.drawable.icon);
         //获取图片的原始的大小
         int width=bmpOrg.getWidth();
         int height=bmpOrg.getHeight();
         
         int newWidth=400;
         int newheight=400;
         //定义缩放的高和宽的尺寸
         float sw=((float)newWidth)/width;
         float sh=((float)newheight)/height;
         //创建操作图片的用的Matrix对象
         Matrix matrix=new Matrix();
        
         matrix.postScale(sw,sh);
         //缩放图片的动作
         matrix.postRotate(30);
         //旋转30*
         Bitmap resizeBitmap=Bitmap.createBitmap(bmpOrg,0,0,width,height,matrix,true);
        
         //创建一个新的图片 
         BitmapDrawable bmp=new BitmapDrawable(resizeBitmap);
        
         //创建Bitmap转换为Drawable对象,使其可以使用在ImageView和ImageButton中
         ImageView imageView=new ImageView(this);
         //创建ImageView的对象
         imageView.setImageDrawable(bmp);
         //将图片设置到中间
         imageView.setScaleType(ScaleType.CENTER);
         //将图片填充之整个视图
         lly.addView(imageView, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
         //添加ImageView到布局模板中
         setContentView(lly);
    }
}
在使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的二进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其中3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程中遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境中安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹中的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值