How to initialize a handler in Android Studio? - java

I've been trying to do timed tasks with a handler in Android Studio, but when I try to initialize it, this happens:
private Handler handler = new Handler() {
#Override
public void publish(LogRecord record) {
}
#Override
public void flush() {
}
#Override
public void close() throws SecurityException {
}
};
Whenever I look at online examples where people use Handlers to execute code at intervals, their declarations look as such:
private Handler handler = new Handler();
How do I avoid the big jumble of methods within the Handler?

Looks like you're trying to use java.util.logging.Handler instead of android.os.Handler. Changing which one you import at the top of the file should fix your problem.
The auto-complete should show you which packages you will be importing from, so watch out for that in the future.

Related

AWS SWF - Workflow passing activity results with signals driving the workflow

I have the requirement to use AWS Simple Workflow (SWF) for an orchestration type of system design. There is parent application that is start this child workflow then signal the workflow to work on activities. I have a workflow that starts up and waits for signals to happen before it can start doing activity work. Once one activity is done then it will report back to by closing out the activity on the parent workflow.
How do I wait for the signal and also use the results from another activity that was invoked by a signal?
Do I need to look into the execution history for the result of an activity and not rely on doing this work in the decide?
Thanks for the help
Code Example:
#SuppressWarnings("unused")
#Slf4j
public class ChildWorkflowImpl implements ChildWorkflow {
private final Settable<Message> firstStepReceived = new Settable<>();
private final Settable<Message> secondStepReceived = new Settable<>();
#Autowired
private FirstActivityClient firstActivityClient;
#Autowired
private SecondActivityClient secondActivityClient;
#Autowired
private AmazonSimpleWorkflow amazonSimpleWorkflow;
#Override
public void startWorkflow(SubsystemMessage subsystemMessage) {
//wait for signal to start
new Task(firstStepReceived) {
#Override
protected void doExecute() throws Throwable {
//Initiate Activity
startStage(firstStepReceived.get(););
}
};
//wait for second signal but pass in data from first activity
new Task(secondStepReceived) {
#Override
protected void doExecute() throws Throwable {
}
};
}
public void firstStep(Message message) {
Promise<FirstActivityResponse> firstActivity = firstActivityClient.execute();
//wait for signal for disable
new Task(firstActivity) {
public void doExecute() {
//report back status for stage by closing parent activity
}
};
}
public void secondStep(FirstActivityResponse response) {
Promise<SecondActivityResponse> secondActivityResponse = secondActivityClient.execute(response);
new Task(secondActivityResponse) {
public void doExecute() {
//report back status for stage
}
};
}
}
You add a signal method to the workflow interface and use Settable to notify the other part of the workflow code about the signal. See Settable documentation from this documentation page.
BTW. I recommend looking at temporal.io which is a greatly improved version of SWF which supports synchronous programming without all these pesky tasks.

add Handler to every Logger

I want to add a custom handler to every logger for every class of my project. I have a logging.properties file, which is read at the very beginning using:
try (InputStream in = ReportingService.class.getResourceAsStream("logging.properties")) {
LogManager.getLogManager().readConfiguration(in);
} catch (IOException ex) {
Logger.getLogger(myClass.class.getName()).log(Level.SEVERE, null, ex);
}
The logging.properties file looks like this:
handlers=java.util.logging.ConsoleHandler,myPackage.AlertHandler
.level=SEVERE
java.util.logging.ConsoleHandler.level=SEVERE
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
myPackage.AlertHandler.level=SEVERE
myPackage.AlertHandler.formatter=java.util.logging.SimpleFormatter
And myPackage.AlertHandler.java looks like this:
package myPackage;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import javafx.scene.control.Alert;
public class AlertHandler extends Handler {
#Override
public void publish(LogRecord lr) {
Alert a = new Alert(Alert.AlertType.ERROR);
a.setTitle("Exception!");
a.setHeaderText("Exception was thrown, here is the StackTrace:");
a.setContentText(getFormatter().formatMessage(lr));
Platform.runLater(()->{a.showAndWait();});
}
#Override
public void flush() {
//no real handler is open, nothing to flush
}
#Override
public void close() throws SecurityException {
//no real handler is open, nothing to close
}
}
The logging file is read without issues, as no more INFO or WARNING messages are printed to the console, only SEVERE. But my custom handler is never called, as no Alert windows are ever opened. I also tried adding the handler to the global logger, in hopes of every other logger inheriting its handlers, but it doesn't work either:
Logger.getGlobal().addHandler(new AlertHandler());
Logger.getLogger("").addHandler(new AlertHandler());
Adding the handler to a specific logger works as intended: if an error is thrown anywhere in the class, an alert window is opened with the stacktrace.
Logger.getLogger("mySecondClass").addHandler(new AlertHandler());
But I want to add this handler to EVERY logger in any class!
But I want to add this handler to EVERY logger in any class!
If you want this handler to see all logger output then you just have to install one instance on the root logger. For example, Logger.getLogger("").addHandler(new AlertHander());
By default, child loggers are going to publish the log records to the parent handers.
The main problem is your code is going to always generate a NullPointerException because you never assigned a formatter to be used with the handler. So the call to getFormatter is going to return null and then fail.
public static void main(String[] args) {
Handler h = new Handler() {
#Override
public void publish(LogRecord record) {
}
#Override
public void flush() {
}
#Override
public void close() throws SecurityException {
}
};
System.out.println(h.getFormatter());
}
You also need to:
Add code to parse the level, formatter, and filter assigned by the log manager for your handler.
Choose sane defaults when no level, formatter, or filter values are defined.
Deal with non-JavaFX Application Threads creating and showing the dialog by using Platform.runLater.
Call isLoggable in your publish method to determine if your handler should publish or not.
Catch runtime exceptions inside your publish method and track them by calling Handler.reportError.
Make life easy and create unit tests to ensure your handler actually works before you try to use it in the wild.

Android Handler getting called repeatedly by Looper in Eclipse instead of Looper discarding message after use

I think I may have accidentally switched on some setting I didn't intent to in Eclipse or something. I'm working on an android game and from within the game logic, when certain events happen I send messages to the main activity to display certain things.
I have the following classes:
public class GameMessageHandler extends Handler {
public static final int DO_SOMETHING = 0;
private final WeakReference<MyActivity> myActivity;
public GameMessageHandler(MyActivity myActivity) {
this.myActivity = new WeakReference<MyActivity>(myActivity);
}
#Override
public void handleMessage(Message msg) {
if (myActivity != null) {
MyActivity activity = myActivity.get();
if (msg.what == DO_SOMETHING) {
//even if the caller only called this one time, this keeps executing forever
activity.doSomething();
}
}
}
}
public class GameEventListenerAndroid implements GameEventListener {
private Handler handler;
public GameEventListenerAndroid(GameMessageHandler gameMessageHandler){
this.handler = gameMessageHandler;
}
#Override
public void playerTookSomeAction() {
//this only gets called one time
handler.sendEmptyMessage(GameMessageHandler.DO_SOMETHING);
}
}
I KNOW this logic works because what I'm trying to run right now is from a backup I saved after I saw it work MULTIPLE times, but as I said what is happening right now is for some reason the Looper keeps calling the message handler with the same message a million times per second and never discards the message to move on to something else.
Any help is greatly appreciated!
Check points:
activity.doSomething() will not send message GameMessageHandler.DO_SOMETHING
playerTookSomeAction() is not called repeatedly
Just format it to be BETTER, incase someone feels so boring!

Own Listener change UI-Thread in Android

#first Sorry for my bad english.
I have created a own Listener. I want to change a TextView, when the Listener is called in the MainActivity from a Service. The idea for my own Listener is from:
http://tseng-blog.nge-web.net/blog/2009/02/17/how-implement-your-own-listener-android-java/
In the Code Example the TriggerMethod() ist called from a Calculation Thread, running in the Service.
I solved the Problem, but I find, it isn't pretty nice, because in every new Activity I have to make a new Thread. Is it possible to create an interface/listener that automatically can change the UI?
Used to solve the Problem:
http://developer.android.com/guide/components/processes-and-threads.html
ResultListener.java:
public interface ResultListener {
public void onResultAvailable(double result);
}
SimuService.java:
public class SimuService extends Service {
private ResultListener mResultListener = null;
public void setResultListener(ResultListener listener){
mResultListener=listener;
}
public void triggerMethode(){
observeResultDouble=getObserveDouble;
mResultListener.onResultAvailable(observeResultDouble);
}
MainActivity:
public class MainActivity extends FragmentActivity{
TextView txtView;
ResultListener mResultListener;
SimuService mSimuService;
protected void onCreate(Bundle savedInstanceState) {
txtView = (TextView) findViewById(R.id.txtServiceTime);
//Create Service .....an Bind
mResultListener = new ResultListener() {
#Override
public void onResultAvailable(double result) {
txtView.setText("Result: "+result);
}
};
mSimuService.setResultListener(mResultListener);
}
MY SOLUTION:
ResultListener = new ResultListener() {
#Override
public void onResultAvailable(double result) {
this.result=result;
runOnUiThread(setNewDataToUI);
}
};
private Thread setNewDataToUI = new Thread(new Runnable() {
#Override
public void run() {
txtView.setText("Result: "+result);
}
});
First of all: If you reference a Service in an Activity, the Service becomes pretty much useless. The advantage of services are, that they are loose coupled and can work indepenendtly form activities (=what the user sees) and its lifecycle and might even be in their own process. Thus activity-service communication is through intents or inter-process language AIDL, not through callbacks. If you want something executed asynchronosly use AsyncTask.
To your main problem: as you found out, you can only modify the UI on the UI-thread. So by design, leave changing UI in the component, thats responsibly for that (either activtiy or fragment), that will prevent the need of runOnUiThread()
Your code seems like txtView.setText("Result: "+result); will be executed in the Activity, but it wont. It will be executed in the Service, which (as I impleied before) does not run on the UI-thread. The problem is, I dont get the intent, what exactly you want to achieve so it is hard to give you an alternative solution.

How to create Android Handler in a Java plugin called from Unity

So, let's say you have a Unity Java plugin, you call into the Java plugin like so
private static readonly AndroidJavaClass m_somePlugin = new AndroidJavaClass("com.unity3d.Plugin.blah.SomePlugin");
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
using (var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
{
m_somePlugin.CallStatic("onInitialise", currentActivity);
}
}
and the plugin looks something like this
public class SomePlugin
{
static public void onInitialise(final Activity currentActivity)
{
Handler someHandler = new Handler();
}
}
All quite simple. Except it will crash. Creating a Handler is the cause. I'm guessing it's a thread issue.
So the question is, how does one create a handler in a Java plugin, in the activity that I'm passing in? Anyone know?
Yes, the solution to the problem was to use runOnUiThread. So in order to get the above code to not crash SomePlugin should look like so
public class SomePlugin
{
static public void onInitialise(final Activity currentActivity)
{
currentActivity.runOnUiThread(new Runnable() {
Handler someHandler = new Handler(); });
}
}

Categories