我有一个TaskManager,它管理我的应用程序中的几个后台任务但是我不断得到NPE错误并在使用时强制关闭问题(我相信由于我在第108行得到致命异常,即:Log。 v(" TaskManager",task.toString());
我尝试设置一个if语句以防止NPE发生但问题仍然存在我不确定如何在没有NPE / Force Close的情况下如何正常停止。
(非常感谢任何输入/答案/建议)
05-21 19:37:15.540: V/TaskManager(3774): In executeTask() on BACKGROUND THREAD
05-21 19:37:15.630: D/dalvikvm(3774): GC_CONCURRENT freed 373K, 8% free 4845K/5256K, paused 4ms+4ms, total 27ms
05-21 19:37:15.660: V/TaskManager(3774): In logTaskInfo() on BACKGROUND THREAD
05-21 19:37:15.660: V/TaskManager(3774): -------------------
05-21 19:37:15.660: V/TaskManager(3774): Task: PingAliveTask
05-21 19:37:15.660: V/TaskManager(3774): Calling Party: TaskManager
05-21 19:37:15.660: V/TaskManager(3774): Scheduled Start Time: 05/21/2014 19:37:15
05-21 19:37:15.660: V/TaskManager(3774): Actual Start Time: 05/21/2014 19:37:15
05-21 19:37:15.660: V/TaskManager(3774): Ending Time: 05/21/2014 19:37:15
05-21 19:37:15.660: V/TaskManager(3774): Execution Result: true
05-21 19:37:15.660: V/TaskManager(3774): -------------------
05-21 19:37:15.660: V/TaskManager(3774): -------------------
05-21 19:37:15.660: V/TaskManager(3774): In run() on BACKGROUND THREAD
05-21 19:37:15.660: V/TaskManager(3774): In startManaging() on BACKGROUND THREAD
05-21 19:37:15.660: V/TaskManager(3774): In requeue() on BACKGROUND THREAD
05-21 19:37:15.660: V/TaskManager(3774): In sortedInsert() on BACKGROUND THREAD
05-21 19:37:15.660: V/TaskManager(3774): Hoping to sleep : 15 seconds
05-21 19:37:30.660: V/TaskManager(3774): In executeTask() on BACKGROUND THREAD
05-21 19:37:30.740: V/TaskManager(3774): In logTaskInfo() on BACKGROUND THREAD
05-21 19:37:30.740: V/TaskManager(3774): -------------------
05-21 19:37:30.740: W/dalvikvm(3774): threadid=14: thread exiting with uncaught exception (group=0x40dcc930)
05-21 19:37:30.740: E/AndroidRuntime(3774): FATAL EXCEPTION: Thread-250
05-21 19:37:30.740: E/AndroidRuntime(3774): java.lang.NullPointerException: println needs a message
05-21 19:37:30.740: E/AndroidRuntime(3774): at android.util.Log.println_native(Native Method)
05-21 19:37:30.740: E/AndroidRuntime(3774): at android.util.Log.v(Log.java:117)
05-21 19:37:30.740: E/AndroidRuntime(3774): at com.new.project.taskmanager.TaskManager.logTaskInfo(TaskManager.java:108)
05-21 19:37:30.740: E/AndroidRuntime(3774): at com.new.project.taskmanager.TaskManager.executeTask(TaskManager.java:180)
05-21 19:37:30.740: E/AndroidRuntime(3774): at com.new.project.taskmanager.TaskManager.startManaging(TaskManager.java:160)
05-21 19:37:30.740: E/AndroidRuntime(3774): at com.new.project.taskmanager.TaskManager.run(TaskManager.java:240)
05-21 19:37:30.740: E/AndroidRuntime(3774): at java.lang.Thread.run(Thread.java:856)
public class TaskManager implements Runnable {
/** Contains the BackgroundTasks to execute. Will always be sorted on BackgroundTask.startTime */
private Vector<BackgroundTask> queue;
/** Task that is executing */
private BackgroundTask currentTask;
/** Contains the current states of the system. At current implementation this will be manipulated externally*/
private Status status;
/** Controls whether TaskManager continues running*/
private boolean KILLSWITCH = false;
/**
* Signal from outside to stop TaskManager.
* <p>
* Testing has concluded that TaskManager will continue execution despite activity ending. In an effort to
* fix any rogue processes, this mechanism has been created. In onPause() or any other relevant method add
* {@link TaskManager#KILL()}.
*/
public void KILL() {
KILLSWITCH = true;
}
/**
* Takes in no parameters, initializes objects queue and Status
*/
public TaskManager() {
initializeQueue();
status = new Status();
//TODO remove these for prod
status.addState(TriggerRule.Offline);
status.addState(TriggerRule.Online);
status.addState(TriggerRule.Periodic);
}
/**
* Currently takes in tasks generated from TaskFactory. Other BackgroundTasks can be registered on the queue
* by using {@link TaskManager#addTask(BackgroundTask)} externally. At this point it is open but the optimal
* approach is probably to leave all the tasks in one area, in TaskFactory.
* @see TaskFactory
*/
private void initializeQueue() {
this.logRunningThread("TaskManager", "initializeQueue()");
queue = new Vector<BackgroundTask>();
for(String s: TaskFactory.getTaskNameList()) {
BackgroundTask bgTask = TaskFactory.getTaskByName(s, this);
if(bgTask != null) {
this.sortedInsert(bgTask);
}
}
}
/**
* Logs information about task to LogCat
* @param task - BackgroundTask to print
*/
private void logTaskInfo(BackgroundTask task) {
this.logRunningThread("TaskManager", "logTaskInfo()");
this.logSeparator("TaskManager");
if (task != null) {
Log.v("TaskManager", task.toString());
logSeparator("TaskManager");
}
try {
synchronized(this) {
this.notify();
}
} catch (Exception e) {e.printStackTrace();
KILL();
}
}
/**
* Main life cycle of the process. In order to be admitted the BackgroundTask must
* meet the required rules set. The current state that the rules are tested against
* are stored in {@link TaskManager#status}.
* <p>
* Does the following:
* <p>
* Invokes {@link TaskManager#requeue()} to swap current process back into queue,
* grabs next scheduled task and sets {@link TaskManager#currentTask}.
* If at or past time to execute, executes {@link TaskManager#currentTask}
* else wait until time and execute {@link TaskManager#currentTask}
*/
private void startManaging() {
this.logRunningThread("TaskManager", "startManaging()");
requeue();
//look at first entity in queue
if(! queue.isEmpty()) {
BackgroundTask t = queue.get(0);
boolean hasMetRules = RuleBook.validate(status, t.getRule());
if(hasMetRules) {
currentTask = t;
queue.remove(t);
Time now = new Time();
now.setToNow();
if(t.getStartTime().before(now)) {
executeTask(now);
}
else {
long millis = t.getStartTime().toMillis(true) - now.toMillis(true);
try {
synchronized (this) {
Log.v("TaskManager", "Hoping to sleep : " + Long.toString(millis / 1000) + " seconds");
Thread.sleep(millis);
}
} catch (Exception e) {e.printStackTrace();}
now.setToNow();
executeTask(now);
}
}
}
}
/**
* Uses java.lang.reflect to execute any Background Task no matter the type.
* This execution is <font color="red"><u><b>blocking</b></u></font>. In other words no further code will execute until
* the AsyncTask's status goes to FINISHED.
* @param now - Recorded time that the process was admitted to processor
*/
private void executeTask(Time now) {
this.logRunningThread("TaskManager", "executeTask()");
currentTask.setActualStartTime(now);
try {
currentTask.getTask().getClass().getMethod("execute", Object[].class).invoke(currentTask.getTask(), new Object[] {null}).getClass().getMethod("get").invoke(currentTask.getTask());
} catch (Exception e) {e.printStackTrace();}
logTaskInfo(currentTask);
}
/**
* If there is a finished task, it will remove it from the currentTask and place it back into
* queue with a new start time.
* @return true if no error during
*/
private boolean requeue() {
this.logRunningThread("TaskManager", "requeue()");
if(currentTask != null) {
try {
BackgroundTask newTask = TaskFactory.getTaskByName(currentTask.getName(), this);
sortedInsert(newTask);
currentTask = null;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
return true;
}
/**
* Inserts into the queue at the earliest possible moment
* <p>
* RT = O(n)
* <p>
* The queue is sorted based on {@link BackgroundTask#startTime }
* @param task BackgroundTask to insert into the queue
*/
private void sortedInsert(BackgroundTask task) {
logRunningThread("TaskManager", "sortedInsert()");
for(int i=0; i<queue.size();i++) {
BackgroundTask t = queue.get(i);
if(task.compareTo(t) <= 0) {
queue.insertElementAt(task, i);
return;
}
}
queue.add(task);
}
/**
* Main loop. Will continue to execute until a signal is received from outside to
* stop via {@link TaskManager#KILL()}.
*/
@Override
public void run() {
logSeparator("TaskManager");
while (! KILLSWITCH) {
logRunningThread("TaskManager", "run()");
startManaging();
logSeparator("TaskManager");
}
}
private void logRunningThread(String tag, String name) {
if(Looper.myLooper() == Looper.getMainLooper()) {
Log.v(tag, "In " + name + " on MAIN THREAD");
}
else {
Log.v(tag, "In " + name + " on BACKGROUND THREAD");
}
}
private void logSeparator(String tag) {
Log.v(tag, "-------------------");
}
public void addTask(BackgroundTask t) {
this.sortedInsert(t);
}
}
答案 0 :(得分:0)
可能是task.toString()返回null