I had to declare a static handler because of some Java nonsense with leaks.
static class ParsingCompleteHandler extends Handler {
private final WeakReference<BackupActivity> mTargetActivity;
ParsingCompleteHandler(BackupActivity targetActivity) {
mTargetActivity = new WeakReference<BackupActivity>(targetActivity);
}
#Override
public void handleMessage(Message msg) {
BackupActivity targetActivity = mTargetActivity.get();
targetActivity.updateDialog();
}
};
Elsewhere in the code (inside a runnable) I was trying to sendEmptyMessage() to this handler
Runnable runnable = new Runnable() {
#Override
public void run() {
lastBackupDataObject = getBackupDataObjectFromFile(file);
parsingCompleteHandler.sendEmptyMessage(0);
}
};
Thread parsingThread = new Thread(runnable);
parsingThread.start();
but since the sendEmptyMessage() method is not static (and the handler now is), obviously I can't do it. And I need to send a message to the handler because that's what it's there for. How do I do it?
You can do this by making your handler object as class global object and than call this message this should work
eg.
public class SomeClass{
ParsingCompleteHandler parsingCompleteHandler;
static class ParsingCompleteHandler extends Handler {
private final WeakReference<BackupActivity> mTargetActivity;
ParsingCompleteHandler(BackupActivity targetActivity) {
mTargetActivity = new WeakReference<BackupActivity>(targetActivity);
}
#Override
public void handleMessage(Message msg) {
BackupActivity targetActivity = mTargetActivity.get();
targetActivity.updateDialog();
}
};
than do
Runnable runnable = new Runnable() {
#Override
public void run() {
lastBackupDataObject = getBackupDataObjectFromFile(file);
parsingCompleteHandler.sendEmptyMessage(0);
}
};
Thread parsingThread = new Thread(runnable);
parsingThread.start();
Related
I am having below code that uses AsyncTask to do some task in background but i would like to migrate to ExecutorService, the problem i am having is that my AsyncTask class has a constructor
Below is my AsyncTask method
private static class UpdateCustomerAsyncTask extends AsyncTask<Customer, Void, Void>{
private CustomerDao customerDao;
public UpdateCustomerAsyncTask(CustomerDao customerDao) {
this.customerDao = customerDao;
}
#Override
protected Void doInBackground(Customer... customers) {
try{
customerDao.updateCustomer(customers[0]);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
The above class is supposed to do the task of updating room database in background
I know how use Executor Service in a simple way but i would like some help when using the ExecutorService with a class which extends the Executor Service like the above way where i have extended AsyncTask
Below is how i tried implementing using Simple Executor Service but i am stuck when extending the Executor Service with a class
int NUMBER_OF_THREADS = 4;
ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
executorService.execute(() -> {
customerDao.updateCustomer(customers[0]);
});
For Executors i think below class is solve your problem and really help full while working with room. Check below
public class AppExecutors {
private final Executor mDiskIO;
private final Executor mNetworkIO;
private final Executor mMainThread;
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
this.mDiskIO = diskIO;
this.mNetworkIO = networkIO;
this.mMainThread = mainThread;
}
public AppExecutors() {
this(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3),
new MainThreadExecutor());
}
public Executor diskIO() {
return mDiskIO;
}
public Executor networkIO() {
return mNetworkIO;
}
public Executor mainThread() {
return mMainThread;
}
private static class MainThreadExecutor implements Executor {
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
#Override
public void execute(#NonNull Runnable command) {
mainThreadHandler.post(command);
}
}
}
And to update your custom use like this.
void updateCustomer(Integer id, Activity context){
YourDatabase database = YourDatabase.getDatabase(context)
AppExecutors appExecutors = new AppExecutors();
appExecutors.getInstance().diskIO().execute(new Runnable() {
#Override
public void run() {
database.customerDao.updateCustomer(customers[id]);
}
});
}
I have such code:
package x.y.z;
public class Test
{
private static class MyRunnable implements Runnable
{
#Override
public void run()
{
System.out.println("World");
}
}
public static void main(String[] args)
{
final Runnable r1 = new Runnable() {
#Override
public void run()
{
System.out.println("Hello");
}
};
final Runnable r2 = new MyRunnable();
r1.run();
r2.run();
}
}
I am working on some code analysis module, and I want to prove that r1 is an anonymous class instance and r2 is not. Both of them are valid objects having the same base class or an interface. How can I do this?
Refinement: All classes are being loaded, so I do not need to analyze the text.
There's the isAnonymousClass method on Class, so:
if (r1.getClass().isAnonymousClass()) {
// ...
I need a Event-Dispatch-Thread in my programm.
I want go from this:
public Controller {
this.login= new Login(this);
}
to this:
public Controller {
Runnable guiCreator = new Runnable() {
public void run() {
this.login= new Login(this);
}
};
SwingUtilities.invokeLater(guiCreator);
}
I know where the mistake in the second version is. But the Login(Controller controller) constructor needs the controller reference...
How i do this?
Try using Controller.this to refer to the outer/top level instance of the class
public Controller() {
Runnable guiCreator = new Runnable() {
public void run() {
login= new Login(Controller.this);
}
};
SwingUtilities.invokeLater(guiCreator);
}
I am attempting to pass the return value from scheduling a task into an anonymous class, but I am running into trouble. If I set the return value to a final variable, it says it is not initialized:
/* Not initialized */
final BukkitTask task = Bukkit.getScheduler().runTaskTimer(plugin, new Runnable() {
public void run() {
/* irrelevant code */
task.cancel();
}
}, 0L, 20L);
I have also attempted passing a variable by calling a method within the anonymous class, however it changes the return type to void and therefore I cannot pass a proper value:
BukkitTask temp = null;
/* Returns void */
temp = Bukkit.getScheduler().runTaskTimer(plugin, new Runnable() {
private BukkitTask task;
public void initTask(BukkitTask task) {
this.task = task;
}
public void run() {
/* irrelevant code */
task.cancel();
}
}.initTask(temp), 0L, 20L);
How can I pass a returned value into an anonymous class within the code?
You can define this class
class Box<T> {
public volatile T value;
}
and use it like this:
final Box<BukkitTask> taskBox = new Box<BukkitTask>();
taskBox.value = Bukkit.getScheduler().runTaskTimer(plugin, new Runnable() {
public void run() {
/* irrelevant code */
taskBox.value.cancel();
}
}, 0L, 20L);
However, taskBox.value in run could still be null depending on when runTaskTimer actually executes the runnable.
My idea, which might sound stupid, would be to create a global variable to which you assign the return value. Then, have a static method that would return this value to you in the anonymous class.
I seem to have figured out an answer rather quickly!
You can change the return type of the init method, and then it will return the proper values for the code!:
BukkitTask task = null;
task = Bukkit.getScheduler().runTaskTimer(plugin, new Runnable() {
private BukkitTask task;
public Runnable initTask(BukkitTask task) {
this.task = task;
return this;
}
public void run() {
/* irrelevant code */
task.cancel();
}
}.initTask(task), 0L, 20L);
I am not sure what are you trying to do. Would Callable instead of Runnable solve the problem? http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html
see this example
public static void main(String[] args) {
final Object objectA[] = new String[1];
new Thread(new Runnable() {
private A refA = null;
public void run() {
objectA[0] = "Hello World or your object";
}
}).start();;
while (objectA[0] == null){
}
System.out.println(objectA[0]);
}
suppose we have these classes and read the comments
class Work {
void doWork(){ }
void commit(){}
}
class MyRunable implements Runnable {
run(){
Work work=new Work();
work.doWork();
//i can't write work.commit() here, because sometimes i want Thread runs both methods
//and sometimes runs only doWork()
}
}
class Tasks{
main(){
MyRunable myRunable=new MyRunable();
Thread t=new Thread(myRunable);
t.start();
//suppose now i need to call commit() method by the same thread (t)
//how can i do that
}
}
also i don't want to use constructor to determine if i want to call both method or not
You could try using a thread pool with a single thread and keep enqueuing methods as needed:
class Tasks {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
final Work work = new Work();
exec.submit(new Runnable() {
public void run() {
work.doWork();
}
});
// later
exec.submit(new Runnable() {
public void run() {
work.commit();
}
});
}
}
This way, both methods will be executed in a sequence by the same thread, but separately.
Add parameter to your class MyRunnable. Call this parameter "runingMode". It could be an enum:
enum RunningMode {
DO_WORK {
public void work(Work work) {
work.doWork();
}
},
COMMIT {
public void work(Work work) {
work.commit();
}
};
public abstract void work();
}
Now your class MyRunnable should have list of modes:
class MyRunable implements Runnable {
private Collection<RunningMode> modes;
MyRunable(Collection<RunningMode> modes) {
this.modes = modes;
}
}
Implement run() method as following:
Work work=new Work();
for (RunningMode mode : modes) {
mode.work(work);
}
work.doWork();
Create instance of your class passing to it the mode you currently need:
MyRunable myRunable=new MyRunable(Arrays.asList(RunningMode.DO_WORK, RunningMode.COMMIT));
You could use an anonymous class.
final boolean condition = ...
Thread t = new Thread(new Runnable() {
public void run() {
Work work=new Work();
work.doWork();
if(condition)
work.commit();
}});
t.start();