/* * Copyright (C) 2007-2015 FBReader.ORG Limited <contact@fbreader.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ package org.geometerplus.android.util; import java.util.Queue; import java.util.LinkedList; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.os.Handler; import android.os.Message; import org.fbreader.util.Pair; import org.geometerplus.zlibrary.core.application.ZLApplication; import org.geometerplus.zlibrary.core.resources.ZLResource; public abstract class UIUtil { private static final Object ourMonitor = new Object(); private static ProgressDialog ourProgress; private static final Queue<Pair<Runnable,String>> ourTaskQueue = new LinkedList<Pair<Runnable,String>>(); private static volatile Handler ourProgressHandler; private static boolean init() { if (ourProgressHandler != null) { return true; } try { ourProgressHandler = new Handler() { public void handleMessage(Message message) { try { synchronized (ourMonitor) { if (ourTaskQueue.isEmpty()) { ourProgress.dismiss(); ourProgress = null; } else { ourProgress.setMessage(ourTaskQueue.peek().Second); } ourMonitor.notify(); } } catch (Exception e) { e.printStackTrace(); ourProgress = null; } } }; return true; } catch (Throwable t) { t.printStackTrace(); return false; } } public static void wait(String key, String param, Runnable action, Context context) { waitInternal(getWaitMessage(key).replace("%s", param), action, context); } public static void wait(String key, Runnable action, Context context) { waitInternal(getWaitMessage(key), action, context); } private static String getWaitMessage(String key) { return ZLResource.resource("dialog").getResource("waitMessage").getResource(key).getValue(); } private static void waitInternal(String message, Runnable action, Context context) { if (!init()) { action.run(); return; } synchronized (ourMonitor) { ourTaskQueue.offer(new Pair(action, message)); if (ourProgress == null) { ourProgress = ProgressDialog.show(context, null, message, true, false); } else { return; } } final ProgressDialog currentProgress = ourProgress; new Thread(new Runnable() { public void run() { while (ourProgress == currentProgress && !ourTaskQueue.isEmpty()) { final Pair<Runnable,String> p = ourTaskQueue.poll(); p.First.run(); synchronized (ourMonitor) { ourProgressHandler.sendEmptyMessage(0); try { ourMonitor.wait(); } catch (InterruptedException e) { } } } } }).start(); } public static ZLApplication.SynchronousExecutor createExecutor(final Activity activity, final String key) { return new ZLApplication.SynchronousExecutor() { private final ZLResource myResource = ZLResource.resource("dialog").getResource("waitMessage"); private final String myMessage = myResource.getResource(key).getValue(); private volatile ProgressDialog myProgress; public void execute(final Runnable action, final Runnable uiPostAction) { activity.runOnUiThread(new Runnable() { public void run() { myProgress = ProgressDialog.show(activity, null, myMessage, true, false); final Thread runner = new Thread() { public void run() { action.run(); activity.runOnUiThread(new Runnable() { public void run() { try { myProgress.dismiss(); myProgress = null; } catch (Exception e) { e.printStackTrace(); } if (uiPostAction != null) { uiPostAction.run(); } } }); } }; runner.setPriority(Thread.MAX_PRIORITY); runner.start(); } }); } private void setMessage(final ProgressDialog progress, final String message) { if (progress == null) { return; } activity.runOnUiThread(new Runnable() { public void run() { progress.setMessage(message); } }); } public void executeAux(String key, Runnable runnable) { setMessage(myProgress, myResource.getResource(key).getValue()); runnable.run(); setMessage(myProgress, myMessage); } }; } }