使用spi机制优化组件的加载
This commit is contained in:
@@ -19,6 +19,7 @@ import com.arialyy.aria.core.inf.IUtil;
|
||||
import com.arialyy.aria.core.listener.IEventListener;
|
||||
import com.arialyy.aria.core.loader.LoaderStructure;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
@@ -34,10 +35,12 @@ public abstract class AbsGroupLoaderUtil implements IUtil {
|
||||
private AbsTaskWrapper mTaskWrapper;
|
||||
private boolean isStop = false, isCancel = false;
|
||||
|
||||
protected AbsGroupLoaderUtil(AbsTaskWrapper wrapper, IEventListener listener) {
|
||||
mTaskWrapper = wrapper;
|
||||
|
||||
@Override public IUtil setParams(AbsTaskWrapper taskWrapper, IEventListener listener) {
|
||||
mTaskWrapper = taskWrapper;
|
||||
mListener = listener;
|
||||
mLoader = getLoader();
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract AbsGroupLoader getLoader();
|
||||
|
||||
@@ -15,20 +15,16 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.group;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.IThreadStateManager;
|
||||
import com.arialyy.aria.core.inf.IUtil;
|
||||
import com.arialyy.aria.core.listener.IDLoadListener;
|
||||
import com.arialyy.aria.core.listener.IEventListener;
|
||||
import com.arialyy.aria.core.listener.ISchedulers;
|
||||
import com.arialyy.aria.core.loader.LoaderStructure;
|
||||
import com.arialyy.aria.core.loader.SubLoader;
|
||||
import com.arialyy.aria.exception.AriaException;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
@@ -49,12 +45,16 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
|
||||
* @param schedulers 调度器
|
||||
* @param needGetInfo {@code true} 需要获取文件信息。{@code false} 不需要获取文件信息
|
||||
*/
|
||||
protected AbsSubDLoadUtil(DTaskWrapper taskWrapper, Handler schedulers, boolean needGetInfo, String parentKey) {
|
||||
mWrapper = taskWrapper;
|
||||
protected AbsSubDLoadUtil(Handler schedulers, boolean needGetInfo, String parentKey) {
|
||||
mSchedulers = schedulers;
|
||||
this.parentKey = parentKey;
|
||||
this.needGetInfo = needGetInfo;
|
||||
}
|
||||
|
||||
@Override public IUtil setParams(AbsTaskWrapper taskWrapper, IEventListener listener) {
|
||||
mWrapper = (DTaskWrapper) taskWrapper;
|
||||
mDLoader = getLoader();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,9 @@ package com.arialyy.aria.core.inf;
|
||||
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.listener.IEventListener;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2016/10/31.
|
||||
@@ -26,6 +28,8 @@ import com.arialyy.aria.core.upload.UploadEntity;
|
||||
*/
|
||||
public interface IUtil {
|
||||
|
||||
IUtil setParams(AbsTaskWrapper taskWrapper, IEventListener listener);
|
||||
|
||||
/**
|
||||
* 获取任务标志
|
||||
*
|
||||
|
||||
@@ -15,26 +15,16 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.listener;
|
||||
|
||||
import android.os.Handler;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.inf.TaskSchedulerType;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.DeleteDRecord;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
|
||||
/**
|
||||
* 下载监听类
|
||||
*/
|
||||
public class BaseDListener extends BaseListener<DownloadEntity, DTaskWrapper, AbsTask<DTaskWrapper>>
|
||||
implements IDLoadListener {
|
||||
|
||||
public BaseDListener(AbsTask<DTaskWrapper> task, Handler outHandler) {
|
||||
super(task, outHandler);
|
||||
}
|
||||
public class BaseDListener extends BaseListener implements IDLoadListener {
|
||||
|
||||
@Override
|
||||
public void onPostPre(long fileSize) {
|
||||
@@ -52,7 +42,7 @@ public class BaseDListener extends BaseListener<DownloadEntity, DTaskWrapper, Ab
|
||||
}
|
||||
|
||||
@Override protected void handleCancel() {
|
||||
int sType = getTask().getSchedulerType();
|
||||
int sType = getTask(DownloadTask.class).getSchedulerType();
|
||||
if (sType == TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY) {
|
||||
mEntity.setComplete(false);
|
||||
mEntity.setState(IEntity.STATE_WAIT);
|
||||
|
||||
@@ -29,22 +29,20 @@ import com.arialyy.aria.util.ErrorHelp;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public abstract class BaseListener<ENTITY extends AbsEntity, TASK_WRAPPER extends AbsTaskWrapper<ENTITY>,
|
||||
TASK extends AbsTask<TASK_WRAPPER>>
|
||||
implements IEventListener {
|
||||
protected static String TAG;
|
||||
protected static final int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
|
||||
public abstract class BaseListener implements IEventListener {
|
||||
protected String TAG = getClass().getSimpleName();
|
||||
static final int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
|
||||
protected SoftReference<Handler> outHandler;
|
||||
private long mLastLen; //上一次发送长度
|
||||
private boolean isFirst = true;
|
||||
private TASK mTask;
|
||||
protected long mLastSaveTime;
|
||||
protected ENTITY mEntity;
|
||||
protected TASK_WRAPPER mTaskWrapper;
|
||||
private AbsTask mTask;
|
||||
long mLastSaveTime;
|
||||
protected AbsEntity mEntity;
|
||||
protected AbsTaskWrapper mTaskWrapper;
|
||||
private boolean isConvertSpeed;
|
||||
private long mUpdateInterval;
|
||||
|
||||
protected BaseListener(TASK task, Handler outHandler) {
|
||||
@Override public IEventListener setParams(AbsTask task, Handler outHandler) {
|
||||
this.outHandler = new SoftReference<>(outHandler);
|
||||
mTask = new WeakReference<>(task).get();
|
||||
mEntity = mTask.getTaskWrapper().getEntity();
|
||||
@@ -54,10 +52,11 @@ public abstract class BaseListener<ENTITY extends AbsEntity, TASK_WRAPPER extend
|
||||
mLastLen = mEntity.getCurrentProgress();
|
||||
mLastSaveTime = System.currentTimeMillis();
|
||||
TAG = CommonUtil.getClassName(getClass());
|
||||
return this;
|
||||
}
|
||||
|
||||
protected TASK getTask() {
|
||||
return mTask;
|
||||
protected <TASK extends AbsTask> TASK getTask(Class<TASK> clazz) {
|
||||
return (TASK) mTask;
|
||||
}
|
||||
|
||||
@Override public void onPre() {
|
||||
|
||||
@@ -15,26 +15,18 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.listener;
|
||||
|
||||
import android.os.Handler;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.inf.TaskSchedulerType;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
import com.arialyy.aria.core.upload.UTaskWrapper;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.task.UploadTask;
|
||||
import com.arialyy.aria.util.DeleteURecord;
|
||||
|
||||
/**
|
||||
* 下载监听类
|
||||
*/
|
||||
public class BaseUListener extends BaseListener<UploadEntity, UTaskWrapper, AbsTask<UTaskWrapper>>
|
||||
implements IUploadListener {
|
||||
|
||||
public BaseUListener(AbsTask<UTaskWrapper> task, Handler outHandler) {
|
||||
super(task, outHandler);
|
||||
}
|
||||
public class BaseUListener extends BaseListener implements IUploadListener {
|
||||
|
||||
@Override protected void handleCancel() {
|
||||
int sType = getTask().getSchedulerType();
|
||||
int sType = getTask(UploadTask.class).getSchedulerType();
|
||||
if (sType == TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY) {
|
||||
mEntity.setComplete(false);
|
||||
mEntity.setState(IEntity.STATE_WAIT);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.arialyy.aria.core.listener;
|
||||
|
||||
import android.os.Handler;
|
||||
import com.arialyy.aria.core.download.DGTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.group.GroupSendParams;
|
||||
@@ -35,15 +34,14 @@ import static com.arialyy.aria.core.task.AbsTask.ERROR_INFO_KEY;
|
||||
/**
|
||||
* Created by Aria.Lao on 2017/7/20. 任务组下载事件
|
||||
*/
|
||||
public class DownloadGroupListener
|
||||
extends BaseListener<DownloadGroupEntity, DGTaskWrapper, AbsTask<DGTaskWrapper>>
|
||||
implements IDGroupListener {
|
||||
public class DownloadGroupListener extends BaseListener implements IDGroupListener {
|
||||
private GroupSendParams<DownloadGroupTask, DownloadEntity> mSeedEntity;
|
||||
|
||||
public DownloadGroupListener(AbsTask<DGTaskWrapper> task, Handler outHandler) {
|
||||
super(task, outHandler);
|
||||
@Override public IEventListener setParams(AbsTask task, Handler outHandler) {
|
||||
IEventListener listener = super.setParams(task, outHandler);
|
||||
mSeedEntity = new GroupSendParams<>();
|
||||
mSeedEntity.groupTask = (DownloadGroupTask) task;
|
||||
return listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,12 +162,13 @@ public class DownloadGroupListener
|
||||
}
|
||||
|
||||
private void saveCurrentLocation() {
|
||||
if (mEntity.getSubEntities() == null || mEntity.getSubEntities().isEmpty()) {
|
||||
DownloadGroupEntity dgEntity = (DownloadGroupEntity) mEntity;
|
||||
if (dgEntity.getSubEntities() == null || dgEntity.getSubEntities().isEmpty()) {
|
||||
ALog.w(TAG, "保存进度失败,子任务为null");
|
||||
return;
|
||||
}
|
||||
long location = 0;
|
||||
for (DownloadEntity e : mEntity.getSubEntities()) {
|
||||
for (DownloadEntity e : dgEntity.getSubEntities()) {
|
||||
location += e.getCurrentProgress();
|
||||
}
|
||||
if (location > mEntity.getFileSize()) {
|
||||
@@ -193,7 +192,7 @@ public class DownloadGroupListener
|
||||
}
|
||||
|
||||
@Override protected void handleCancel() {
|
||||
int sType = getTask().getSchedulerType();
|
||||
int sType = getTask(DownloadGroupTask.class).getSchedulerType();
|
||||
if (sType == TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY) {
|
||||
mEntity.setComplete(false);
|
||||
mEntity.setState(IEntity.STATE_WAIT);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.listener;
|
||||
|
||||
import android.os.Handler;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
import com.arialyy.aria.exception.AriaException;
|
||||
|
||||
/**
|
||||
@@ -23,6 +25,8 @@ import com.arialyy.aria.exception.AriaException;
|
||||
*/
|
||||
public interface IEventListener {
|
||||
|
||||
IEventListener setParams(AbsTask task, Handler outHandler);
|
||||
|
||||
/**
|
||||
* 预处理,有时有些地址链接比较慢,这时可以先在这个地方出来一些界面上的UI,如按钮的状态
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.arialyy.aria.core.loader;
|
||||
import com.arialyy.aria.core.inf.IUtil;
|
||||
import com.arialyy.aria.core.listener.IEventListener;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.exception.AriaException;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
@@ -34,10 +35,14 @@ public abstract class AbsNormalLoaderUtil implements IUtil {
|
||||
private AbsTaskWrapper mTaskWrapper;
|
||||
private boolean isStop = false, isCancel = false;
|
||||
|
||||
protected AbsNormalLoaderUtil(AbsTaskWrapper wrapper, IEventListener listener) {
|
||||
mTaskWrapper = wrapper;
|
||||
protected AbsNormalLoaderUtil() {
|
||||
}
|
||||
|
||||
@Override public IUtil setParams(AbsTaskWrapper taskWrapper, IEventListener listener) {
|
||||
mTaskWrapper = taskWrapper;
|
||||
mListener = listener;
|
||||
mLoader = getLoader();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -64,7 +64,7 @@ public abstract class AbsTask<TASK_WRAPPER extends AbsTaskWrapper>
|
||||
return mOutHandler;
|
||||
}
|
||||
|
||||
protected synchronized IUtil getUtil() {
|
||||
synchronized IUtil getUtil() {
|
||||
if (mUtil == null) {
|
||||
mUtil = ComponentUtil.getInstance().buildUtil(mTaskWrapper, mListener);
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ import com.arialyy.aria.util.ComponentUtil;
|
||||
/**
|
||||
* Created by lyy on 2017/2/23. 所有任务实体的父类
|
||||
*/
|
||||
public abstract class AbsTaskWrapper<ENTITY extends AbsEntity>
|
||||
implements ITaskWrapper {
|
||||
public abstract class AbsTaskWrapper<ENTITY extends AbsEntity> implements ITaskWrapper {
|
||||
|
||||
/**
|
||||
* 刷新信息 {@code true} 重新刷新下载信息
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.exception;
|
||||
|
||||
public class AriaComponentException extends RuntimeException {
|
||||
public AriaComponentException(String message, Exception e) {
|
||||
super(message, e);
|
||||
}
|
||||
|
||||
public AriaComponentException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* aria 服务加载器
|
||||
* 参考{@link ServiceLoader}
|
||||
*/
|
||||
public class AriaServiceLoader<S> {
|
||||
|
||||
private static final String PREFIX = "META-INF/services/";
|
||||
|
||||
// The class or interface representing the service being loaded
|
||||
private final Class<S> service;
|
||||
|
||||
// The class loader used to locate, load, and instantiate providers
|
||||
private final ClassLoader loader;
|
||||
|
||||
// The access control context taken when the ServiceLoader is created
|
||||
// Android-changed: do not use legacy security code.
|
||||
// private final AccessControlContext acc;
|
||||
|
||||
private LazyLoader lazyLoader;
|
||||
|
||||
public void reload() {
|
||||
lazyLoader = new LazyLoader(service, loader);
|
||||
}
|
||||
|
||||
private AriaServiceLoader(Class<S> svc, ClassLoader cl) {
|
||||
service = svc;
|
||||
loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
|
||||
// Android-changed: Do not use legacy security code.
|
||||
// On Android, System.getSecurityManager() is always null.
|
||||
// acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
|
||||
reload();
|
||||
}
|
||||
|
||||
public static <S> AriaServiceLoader<S> load(Class<S> service, ClassLoader loader) {
|
||||
return new AriaServiceLoader<>(service, loader);
|
||||
}
|
||||
|
||||
public static <S> AriaServiceLoader<S> load(Class<S> service) {
|
||||
Thread.currentThread().setContextClassLoader(AriaServiceLoader.class.getClassLoader());
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
return AriaServiceLoader.load(service, cl);
|
||||
}
|
||||
|
||||
public S getService(String serviceName) {
|
||||
return lazyLoader.loadService(serviceName);
|
||||
}
|
||||
|
||||
private class LazyLoader {
|
||||
private Class<S> service;
|
||||
private ClassLoader loader;
|
||||
private Enumeration<URL> configs = null;
|
||||
private Iterator<String> pending = null;
|
||||
|
||||
private LazyLoader(Class<S> service, ClassLoader loader) {
|
||||
this.service = service;
|
||||
this.loader = loader;
|
||||
parseConfig();
|
||||
}
|
||||
|
||||
// Parse the content of the given URL as a provider-configuration file.
|
||||
//
|
||||
// @param service
|
||||
// The service type for which providers are being sought;
|
||||
// used to construct error detail strings
|
||||
//
|
||||
// @param u
|
||||
// The URL naming the configuration file to be parsed
|
||||
//
|
||||
// @return A (possibly empty) iterator that will yield the provider-class
|
||||
// names in the given configuration file that are not yet members
|
||||
// of the returned set
|
||||
//
|
||||
// @throws ServiceConfigurationError
|
||||
// If an I/O error occurs while reading from the given URL, or
|
||||
// if a configuration-file format error is detected
|
||||
//
|
||||
private Iterator<String> parse(Class<?> service, URL u) throws ServiceConfigurationError {
|
||||
InputStream in = null;
|
||||
BufferedReader r = null;
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
try {
|
||||
in = u.openStream();
|
||||
r = new BufferedReader(new InputStreamReader(in, "utf-8"));
|
||||
int lc = 1;
|
||||
while ((lc = parseLine(service, u, r, lc, names)) >= 0) ;
|
||||
} catch (IOException x) {
|
||||
fail(service, "Error reading configuration file", x);
|
||||
} finally {
|
||||
try {
|
||||
if (r != null) r.close();
|
||||
if (in != null) in.close();
|
||||
} catch (IOException y) {
|
||||
fail(service, "Error closing configuration file", y);
|
||||
}
|
||||
}
|
||||
return names.iterator();
|
||||
}
|
||||
|
||||
private void fail(Class<?> service, String msg, Throwable cause)
|
||||
throws ServiceConfigurationError {
|
||||
throw new ServiceConfigurationError(service.getName() + ": " + msg,
|
||||
cause);
|
||||
}
|
||||
|
||||
private void fail(Class<?> service, String msg)
|
||||
throws ServiceConfigurationError {
|
||||
throw new ServiceConfigurationError(service.getName() + ": " + msg);
|
||||
}
|
||||
|
||||
private void fail(Class<?> service, URL u, int line, String msg)
|
||||
throws ServiceConfigurationError {
|
||||
fail(service, u + ":" + line + ": " + msg);
|
||||
}
|
||||
|
||||
// Parse a single line from the given configuration file, adding the name
|
||||
// on the line to the names list.
|
||||
//
|
||||
private int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
|
||||
List<String> names)
|
||||
throws IOException, ServiceConfigurationError {
|
||||
String ln = r.readLine();
|
||||
if (ln == null) {
|
||||
return -1;
|
||||
}
|
||||
int ci = ln.indexOf('#');
|
||||
if (ci >= 0) ln = ln.substring(0, ci);
|
||||
ln = ln.trim();
|
||||
int n = ln.length();
|
||||
if (n != 0) {
|
||||
if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
|
||||
fail(service, u, lc, "Illegal configuration-file syntax");
|
||||
}
|
||||
int cp = ln.codePointAt(0);
|
||||
if (!Character.isJavaIdentifierStart(cp)) {
|
||||
fail(service, u, lc, "Illegal provider-class name: " + ln);
|
||||
}
|
||||
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
|
||||
cp = ln.codePointAt(i);
|
||||
if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
|
||||
fail(service, u, lc, "Illegal provider-class name: " + ln);
|
||||
}
|
||||
}
|
||||
if (!names.contains(ln)) {
|
||||
names.add(ln);
|
||||
}
|
||||
}
|
||||
return lc + 1;
|
||||
}
|
||||
|
||||
private S loadService(String serviceName) {
|
||||
while (pending.hasNext()) {
|
||||
if (pending.next().equals(serviceName)) {
|
||||
Class<?> c = null;
|
||||
try {
|
||||
c = Class.forName(serviceName, false, loader);
|
||||
} catch (ClassNotFoundException x) {
|
||||
fail(service,
|
||||
// Android-changed: Let the ServiceConfigurationError have a cause.
|
||||
"Provider " + serviceName + " not found", x);
|
||||
// "Provider " + cn + " not found");
|
||||
}
|
||||
if (!service.isAssignableFrom(c)) {
|
||||
// Android-changed: Let the ServiceConfigurationError have a cause.
|
||||
ClassCastException cce = new ClassCastException(
|
||||
service.getCanonicalName() + " is not assignable from " + c.getCanonicalName());
|
||||
fail(service,
|
||||
"Provider " + serviceName + " not a subtype", cce);
|
||||
// fail(service,
|
||||
// "Provider " + cn + " not a subtype");
|
||||
}
|
||||
try {
|
||||
return service.cast(c.newInstance());
|
||||
} catch (Throwable x) {
|
||||
fail(service, "Provider " + serviceName + " could not be instantiated", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(); // This cannot happen
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析配置文件
|
||||
*/
|
||||
private void parseConfig() {
|
||||
if (configs == null) {
|
||||
try {
|
||||
String fullName = PREFIX + service.getName();
|
||||
if (loader == null) {
|
||||
configs = ClassLoader.getSystemResources(fullName);
|
||||
} else {
|
||||
configs = loader.getResources(fullName);
|
||||
}
|
||||
} catch (IOException x) {
|
||||
fail(service, "Error locating configuration files", x);
|
||||
}
|
||||
}
|
||||
while ((pending == null) || !pending.hasNext()) {
|
||||
if (!configs.hasMoreElements()) {
|
||||
return;
|
||||
}
|
||||
pending = parse(service, configs.nextElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,9 @@ import com.arialyy.aria.core.listener.IEventListener;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.exception.AriaComponentException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -44,9 +43,12 @@ public class ComponentUtil {
|
||||
|
||||
private String TAG = CommonUtil.getClassName(getClass());
|
||||
private static volatile ComponentUtil INSTANCE = null;
|
||||
private AriaServiceLoader<IUtil> utilLoader;
|
||||
private AriaServiceLoader<IEventListener> listenerLoader;
|
||||
|
||||
private ComponentUtil() {
|
||||
|
||||
utilLoader = AriaServiceLoader.load(IUtil.class);
|
||||
listenerLoader = AriaServiceLoader.load(IEventListener.class);
|
||||
}
|
||||
|
||||
public static ComponentUtil getInstance() {
|
||||
@@ -99,12 +101,12 @@ public class ComponentUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载工具
|
||||
* 创建任务工具
|
||||
*
|
||||
* @return 返回下载工具,创建失败返回null
|
||||
* @return 返回任务工具
|
||||
*/
|
||||
public synchronized <T extends IUtil> T buildUtil(AbsTaskWrapper wrapper,
|
||||
IEventListener listener) {
|
||||
public synchronized IUtil buildUtil(AbsTaskWrapper wrapper, IEventListener listener) {
|
||||
utilLoader.reload();
|
||||
int requestType = wrapper.getRequestType();
|
||||
String className = null;
|
||||
switch (requestType) {
|
||||
@@ -139,29 +141,11 @@ public class ComponentUtil {
|
||||
className = "com.arialyy.aria.sftp.upload.SFtpULoaderUtil";
|
||||
break;
|
||||
}
|
||||
if (className == null) {
|
||||
ALog.e(TAG, "不识别的类名:" + className);
|
||||
return null;
|
||||
IUtil util = utilLoader.getService(className);
|
||||
if (util == null) {
|
||||
throw new AriaComponentException("加载工具异常,请求类型:" + wrapper.getRequestType());
|
||||
}
|
||||
T util = null;
|
||||
try {
|
||||
Class<T> clazz = (Class<T>) getClass().getClassLoader().loadClass(className);
|
||||
Class[] paramTypes = { AbsTaskWrapper.class, IEventListener.class };
|
||||
Object[] params = { wrapper, listener };
|
||||
Constructor<T> con = clazz.getConstructor(paramTypes);
|
||||
util = con.newInstance(params);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return util;
|
||||
return util.setParams(wrapper, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +154,7 @@ public class ComponentUtil {
|
||||
* @param wrapperType 任务类型{@link ITaskWrapper}
|
||||
* @return 返回事件监听,如果创建失败返回null
|
||||
*/
|
||||
public synchronized <T extends IEventListener> T buildListener(int wrapperType, AbsTask task,
|
||||
public synchronized IEventListener buildListener(int wrapperType, AbsTask task,
|
||||
Handler outHandler) {
|
||||
String className = null, errorStr = "请添加FTP插件";
|
||||
switch (wrapperType) {
|
||||
@@ -197,25 +181,12 @@ public class ComponentUtil {
|
||||
if (className == null) {
|
||||
return null;
|
||||
}
|
||||
T listener = null;
|
||||
try {
|
||||
Class<T> clazz = (Class<T>) getClass().getClassLoader().loadClass(className);
|
||||
Class[] paramTypes = { AbsTask.class, Handler.class };
|
||||
Object[] params = { task, outHandler };
|
||||
Constructor<T> con = clazz.getConstructor(paramTypes);
|
||||
listener = con.newInstance(params);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException(errorStr);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
IEventListener listener = listenerLoader.getService(className);
|
||||
if (listener == null) {
|
||||
throw new AriaComponentException(errorStr);
|
||||
}
|
||||
return listener;
|
||||
return listener.setParams(task, outHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user