在需要把一个类的数据,实时的传给另一个类时,这个时候有个很简单的方法,就是使用接口回调,来传给实现接口的类。具体实现如下:
//首先在一个类中定义一个接口,和一个初始化callback的方法
//例如:
public interface ValueCallBack {
public void refreshOTAStatus(int OTAStatus, int progress);
}
public void SetCallBack(ValueCallBack callback){
if (mCallback ==null) {
mCallback = callback;
}
}
//然后在这个类里面定义一个mCallback
public ValueCallBack mCallback;
//在实现这个接口的类中重写这个方法refreshOTAStatus
public class OTAUpdateService extends Service implements ROTAUpdateManager.ValueCallBack {
xxxxxxxxxxxxx
@Override
public void refreshOTAStatus(int OTAStatus, int progress) {
android.util.Log.i(TAG,"refreshOTAStatus" + "OTAStatus:" + OTAStatus +",progress:" + progress );
}
xxxxxxxxxxxxx
}
//我们在这个类中通过SetCallBack,将自己传给我们调用的这个类
mROTAUpdateManager = new ROTAUpdateManager(context,handler,path,rebootNow);
mROTAUpdateManager.SetCallBack(this);
//然后在我们调用的类中进行callback的调用即可
mCallback.refreshOTAStatus(value_a,value_b);
//在每次调用mCallback.refreshOTAStatus(value_a,value_b);都会通过另一个类的refreshOTAStatus来打印出具体的内容,也同时可这这里实现我们需要的逻辑
例子对应的两个具体实现:
ROTAUpdateManager.java
package com.mediatek.settings;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import android.os.PowerManager;
import android.os.UpdateEngine;
import android.os.UpdateEngineCallback;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import android.text.TextUtils;
import android.content.Intent;
import android.content.ContentResolver;
import android.provider.Settings;
import com.xchengtech.ProjectConfig;
import com.android.settings.R;
public class ROTAUpdateManager {
private String TAG = "ROTAUpdateManager";
private UpdateEngine mUpdateEngine;
private final UpdateParser.ParsedUpdate parsedUpdate;
private static final String REBOOT_REASON = "reboot-ab-update";
private Context mContext;
private Handler mHandler;
private PowerManager mPowerManager;
private boolean rebootNow;
private PowerManager.WakeLock wakeLock;
private static int otaIsUpgrading = -1;
private File otaDir;
private UpdateEngineCallback mUpdateEngineCallback;
private boolean isCallbackHandled = false;
private boolean isDeleteFiles = false;
public ValueCallBack mCallback;
public ROTAUpdateManager(Context context, Handler handler, String updateFilePath, boolean rebootNow) throws IOException {
this.mContext = context;
this.mHandler = handler;
this.rebootNow = rebootNow;
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
parsedUpdate = UpdateParser.parse(new File(updateFilePath));
Log.e(TAG, "onStatusUpdate status = " + parsedUpdate);
otaDir = new File(updateFilePath);
}
public void startUpdateSystem() throws Exception {
if ( mUpdateEngine == null) {
Log.d(TAG,"new mUpdateEngine");
mUpdateEngine = new UpdateEngine();
}
if (isUpdating()) {
cancelUpdate();
}
try {
if (wakeLock != null) {
wakeLock.acquire();
Log.d(TAG, ",otaIsUpgrading wakeLock.acquire()");
}
if(mUpdateEngineCallback != null){
mUpdateEngineCallback = null;
}
mUpdateEngineCallback = new UpdateEngineCallback() {
@Override
public void onStatusUpdate(int status, float percent) {
otaIsUpgrading = status;
Log.d(TAG, "onStatusUpdate status = " + status + "; percent = " + percent);
handleStatusUpdate(status, percent);
}
@Override
public void onPayloadApplicationComplete(int errorCode) {
if (!isCallbackHandled) {
Log.e(TAG, "onPayloadApplicationComplete errorCode = " + errorCode);
String errMsg = handlePayloadApplicationComplete(errorCode);
boolean success;
if (errMsg.equals("SUCCESS")) {
success = true;
} else {
success = false;
mUpdateEngine.unbind();
Settings.System.putInt(mContext.getContentResolver(),"update.start.status",0);
}
if (isDeleteFiles) {
deleteFiles(otaDir);
}
if (wakeLock != null) {
wakeLock.release();
Log.d(TAG, ", otaIsUpgraded wakeLock.release()");
}
isCallbackHandled = true;
}
}
};
mUpdateEngine.bind(mUpdateEngineCallback);
mUpdateEngine.applyPayload(parsedUpdate.mUrl, parsedUpdate.mOffset, parsedUpdate.mSize, parsedUpdate.mProps);
isCallbackHandled = false;
} catch (Exception e) {
Log.e(TAG,"Ota upgrade failed");
mUpdateEngine.unbind();
showToast(mContext.getResources().getString(R.string.ota_isok));
e.printStackTrace();
}
}
private void deleteFiles(File file) {
if (file.exists() && file.length() == 0) {
Log.d(TAG, "OTA文件目录还未创建,请先点击获取ota升级路径");
}
Log.d(TAG, "删除OTA路径及其中的文件");
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
deleteFiles(f);
}
}
}
file.delete();
}
private boolean isUpdating() {
return otaIsUpgrading != -1;
}
private void cancelUpdate() {
try {
mUpdateEngine.cancel();
Log.d(TAG,"cancle update:");
} catch (Exception e) {
e.printStackTrace();
}
}
private void showToast(String msg) {
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}
});
}
private void handleStatusUpdate(int status, float percent) {
switch (status) {
case UpdateStatusConstants.UPDATE_AVAILABLE:
showToast("start update");
Settings.System.putInt(mContext.getContentResolver(),"update.start.status", 1);
break;
case UpdateStatusConstants.VERIFYING:
break;
case UpdateStatusConstants.DOWNLOADING:
int progress = Float.valueOf(percent * 100).intValue();
if (mCallback != null) {
mCallback.refreshOTAStatus(UpdateStatusConstants.DOWNLOADING,progress);
}
break;
case UpdateStatusConstants.FINALIZING:
int value = Float.valueOf(percent * 100).intValue();
if (mCallback != null) {
mCallback.refreshOTAStatus(UpdateStatusConstants.FINALIZING,value);
}
break;
case UpdateStatusConstants.UPDATED_NEED_REBOOT:
if (rebootNow) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mPowerManager.reboot(REBOOT_REASON);
}
}, 2000);
break;
}
}
public interface ValueCallBack {
public void refreshOTAStatus(int OTAStatus, int progress);
}
public void SetCallBack(ValueCallBack callback){
if (mCallback ==null) {
mCallback = callback;
}
}
private String handlePayloadApplicationComplete(int errorCode) {
String errorMsg = "";
if (wakeLock != null) {
wakeLock.release();
wakeLock = null;
}
switch (errorCode) {
case ErrorCodeConstants.SUCCESS:
errorMsg = "SUCCESS";
otaIsUpgrading = -1;
break;
case ErrorCodeConstants.FILESYSTEM_COPIER_ERROR:
errorMsg = "filesystem copier error";
break;
case ErrorCodeConstants.POST_INSTALL_RUNNER_ERROR:
errorMsg = "an error in running post-install hooks.";
break;
case ErrorCodeConstants.PAYLOAD_MISMATCHED_TYPE_ERROR:
errorMsg = "a mismatching payload";
break;
case ErrorCodeConstants.INSTALL_DEVICE_OPEN_ERROR:
errorMsg = "an error in opening devices";
break;
case ErrorCodeConstants.KERNEL_DEVICE_OPEN_ERROR:
errorMsg = "an error in opening kernel device";
break;
case ErrorCodeConstants.DOWNLOAD_TRANSFER_ERROR:
errorMsg = "an error in fetching the payload";
break;
case ErrorCodeConstants.PAYLOAD_HASH_MISMATCH_ERROR:
errorMsg = "a mismatch in payload hash";
break;
case ErrorCodeConstants.PAYLOAD_SIZE_MISMATCH_ERROR:
errorMsg = "a mismatch in payload size";
break;
case ErrorCodeConstants.DOWNLOAD_PAYLOAD_VERIFICATION_ERROR:
errorMsg = "failing to verify payload signatures";
break;
case ErrorCodeConstants.NOT_ENOUGH_SPACE:
errorMsg = "there is not enough space on the device to apply the update";
break;
case ErrorCodeConstants.PAYLOAD_TIMESTAMP_ERROR:
errorMsg = "an update failed to apply due to a downgrade in payload timestamp.";
break;
case ErrorCodeConstants.OTHER_SITUATION:
errorMsg = "The system is busy, please upgrade later or do not click on upgrade again";
break;
}
showToast(errorMsg);
return errorMsg;
}
public static final class UpdateStatusConstants {
/**
* Update status code: update engine is in idle state.
*/
public static final int IDLE = 0;
/**
* Update status code: update engine is checking for update.
*/
public static final int CHECKING_FOR_UPDATE = 1;
/**
* Update status code: an update is available.
*/
public static final int UPDATE_AVAILABLE = 2;
/**
* Update status code: update engine is downloading an update.
*/
public static final int DOWNLOADING = 3;
/**
* Update status code: update engine is verifying an update.
*/
public static final int VERIFYING = 4;
/**
* Update status code: update engine is finalizing an update.
*/
public static final int FINALIZING = 5;
/**
* Update status code: an update has been applied and is pending for
* reboot.
*/
public static final int UPDATED_NEED_REBOOT = 6;
/**
* Update status code: update engine is reporting an error event.
*/
public static final int REPORTING_ERROR_EVENT = 7;
/**
* Update status code: update engine is attempting to rollback an
* update.
*/
public static final int ATTEMPTING_ROLLBACK = 8;
/**
* Update status code: update engine is in disabled state.
*/
public static final int DISABLED = 9;
}
public static final class ErrorCodeConstants {
/**
* Error code: a request finished successfully.
*/
public static final int SUCCESS = 0;
/**
* Error code: a request failed due to a generic error.
*/
public static final int ERROR = 1;
/**
* Error code: an update failed to apply due to filesystem copier
* error.
*/
public static final int FILESYSTEM_COPIER_ERROR = 4;
/**
* Error code: an update failed to apply due to an error in running
* post-install hooks.
*/
public static final int POST_INSTALL_RUNNER_ERROR = 5;
/**
* Error code: an update failed to apply due to a mismatching payload.
*/
public static final int PAYLOAD_MISMATCHED_TYPE_ERROR = 6;
/**
* Error code: an update failed to apply due to an error in opening devices.
*/
public static final int INSTALL_DEVICE_OPEN_ERROR = 7;
/**
* Error code: an update failed to apply due to an error in opening kernel device.
*/
public static final int KERNEL_DEVICE_OPEN_ERROR = 8;
/**
* Error code: an update failed to apply due to an error in fetching the payload.
*/
public static final int DOWNLOAD_TRANSFER_ERROR = 9;
/**
* Error code: an update failed to apply due to a mismatch in payload hash.
*/
public static final int PAYLOAD_HASH_MISMATCH_ERROR = 10;
/**
* Error code: an update failed to apply due to a mismatch in payload size.
*/
public static final int PAYLOAD_SIZE_MISMATCH_ERROR = 11;
/**
* Error code: an update failed to apply due to failing to verify payload signatures.
*/
public static final int DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 12;
/**
* Error code: an update failed to apply due to a downgrade in payload timestamp.
*/
public static final int PAYLOAD_TIMESTAMP_ERROR = 51;
/**
* Error code: an update has been applied successfully but the new slot
* hasn't been set to active.
*/
public static final int UPDATED_BUT_NOT_ACTIVE = 52;
/**
* Error code: there is not enough space on the device to apply the update. User should
* be prompted to free up space and re-try the update.
*/
public static final int NOT_ENOUGH_SPACE = 60;
/**
* Error code: the device is corrupted and no further updates may be applied.
*/
public static final int DEVICE_CORRUPTED = 61;
/**
* Error code: Other abnormal situations
*/
public static final int OTHER_SITUATION = 48 ;
}
}
OTAUpdateService.java
package com.mediatek.settings;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.content.Context;
import android.os.Looper;
import android.util.Log;
import android.os.IBinder;
public class OTAUpdateService extends Service implements ROTAUpdateManager.ValueCallBack {
private static final String TAG = "OTAUpdateService";
private ROTAUpdateManager mROTAUpdateManager;
private Handler mHandler;
public OTAUpdateService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
mHandler = new Handler(Looper.getMainLooper());
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
if (intent != null){
String pathString = intent.getStringExtra("path");
boolean rebootNow = intent.getBooleanExtra("rebootNow",true);
StartOtaUpgrade(getApplicationContext(),mHandler,pathString,rebootNow);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void StartOtaUpgrade(Context context,Handler handler,String path,boolean rebootNow){
try {
if(mROTAUpdateManager != null){
mROTAUpdateManager = null;
}
mROTAUpdateManager = new ROTAUpdateManager(context,handler,path,rebootNow);
// start callback
mROTAUpdateManager.SetCallBack(this);
mROTAUpdateManager.startUpdateSystem();
Log.d(TAG, "start ota upgrade");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void refreshOTAStatus(int OTAStatus, int progress) {
android.util.Log.i(TAG,"refreshOTAStatus" + "OTAStatus:" + OTAStatus +",progress:" + progress );
}
}