Eclipse Plugin - execute when user changes window in perspective - eclipse-plugin

I would like to ask how would you automatically execute a plugin when a user switches windows in the perspective.
Can this be done maybe with startup handler and IWorkbench?

You can use IPartListener to listen to changes in which part is active.
You can set this up in using IStartup but you need to do this using something like this:
public class StartUp implements IStartup
{
#Override
public void earlyStartup()
{
IWorkbench workbench = PlatformUI.getWorkbench();
workbench.getDisplay().asyncExec(new Runnable() {
#Override
public void run() {
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window != null) {
window.getPartService().addPartListener(your part listener);
}
}
});
}
}
This is using Display.asyncExec to delay setting up the part listener until after the startup has completed as the workbench window will not be available when earlyStartup runs.

Related

How do I make the "user operation is waiting" dialog invisible in Eclipse RCP?

I'm creating a web development framework with Eclipse RCP.
The wizard is creating a feature that creates a project when you press Finish.
I want to show Process Monitor at the bottom of the wizard
I wrote the code as below.
public abstract class CreateProjectWizard extends Wizard {
public CreateProjectWizard () {
...
setNeedsProgressMonitor(true);
}
...
#Override
public boolean performFinish() {
IRunnableWithProgress runnable= new IRunnableWithProgress() {
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
...
IStatus status = createProject(input, monitor);
...
}
};
try {
getContainer().run(true, true, runnable);
}
...
return true;
}
}
How do I make the "user operation is waiting" dialog invisible?
I will let you know if you need additional information.
It looks like you should be able to call Dialog.setBlockedHandler with something that implements IDialogBlockedHandler to change this dialog (both in org.eclipse.jface.dialogs).
The blocked handler does not have to display a dialog, the default JFace handler is just:
new IDialogBlockedHandler() {
#Override
public void clearBlocked() {
// No default behavior
}
#Override
public void showBlocked(IProgressMonitor blocking,
IStatus blockingStatus, String blockedName) {
// No default behavior
}
#Override
public void showBlocked(Shell parentShell, IProgressMonitor blocking,
IStatus blockingStatus, String blockedName) {
// No default behavior
}
};
Eclipse normally replaces this with org.eclipse.ui.internal.dialogs.WorkbenchDialogBlockedHandler which shows the dialog you see (BlockedJobsDialog).
Note that this will not stop the operation waiting for the blocking jobs to finish it will just stop the dialog appearing.

How to avoid Blockhound catching blocking call when setting up data?

In my integration test I'm using BlockHound to capture any blocking call.
For setting up the data I am doing a blocking call because I want the data to be persisted in the DB when running each test.
When running the integration test Blockhound is throwing an error at the set up method: reactor.blockhound.BlockingOperationError: Blocking call! java.io.FileInputStream#readBytes
How to avoid this?
#BeforeAll
public static void blockHoundSetup() {
BlockHound.install();
}
#BeforeEach
public void setUp() {
stagingAreaAdapter.deleteAll()
.thenMany(Flux.fromIterable(data))
.flatMap(stagingAreaAdapter::save)
.blockLast();
}
Check BlockHound customizations for allowing and disallowing blocking calls inside methods:
https://github.com/reactor/BlockHound/blob/master/docs/customization.md#dis-allowing-blocking-calls-inside-methods
1. using builder in a #BeforeAll method (as per #KrisKris1):
#BeforeAll
public static void blockHoundSetup() {
BlockHound.builder().allowBlockingCallsInside(
TestClass.class.getName(), "setUp").install();
}
or
2. via implementing the BlockHoundIntegration interface (still applies globally):
public class BlockHoundCustomConfiguration implements BlockHoundIntegration {
#Override
public void applyTo(BlockHound.Builder builder) {
builder.allowBlockingCallsInside("java.base/java.io.RandomAccessFile", "readBytes");
}
}
and create the following file:
<project dir>/src/test/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration
with your custom class:
com.example.config.BlockHoundCustomConfiguration
You need to allow blocking method calls inside java.util.zip.InflaterInputStream#read down the callstack.
Add in your BlockHound customization config.
public class ReactorBlockHoundIntegration implements BlockHoundIntegration {
#Override
public void applyTo(BlockHound.Builder builder) {
builder.allowBlockingCallsInside(InflaterInputStream.class.getName(), "read");
}
}
https://docs.oracle.com/javase/8/docs/api/index.html?java/util/zip/package-summary.html

How to create custom native module android for react native app?

I've build simple service in android studio to run a service every second in console log,
and I want to implement my android studio code in react native
there's a way to do that?
let say I've a code :
myService.class
public class myService extends Service {
private Handler handler= new Handler();
private boolean run = true;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onStart(Intent i, int startId){
super.onStart(i, startId);
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (run){
Log.e("Second", "test");
}
handler.postDelayed(this,1000);
}
},1000);
}
public void onDestroy(){
super.onDestroy();
run=false;
Log.d("Test", "Screen on");
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onPause() {
super.onPause();
Log.d("Test", "Screen off");
startService(new Intent(this, myService.class));
}
#Override
protected void onResume() {
super.onResume();
startService(new Intent(this, myService.class));
}
}
You can use RN Native modules. For background tasks Headless JS is useful. And for listening events LifecycleEventListener is what you are looking for. getReactApplicationContext().startService(new Intent(getReactApplicationContext(), myService.class) will do the rest. I am ready for further help
Please refer to https://facebook.github.io/react-native/docs/native-modules-android
You can follow the docs: https://facebook.github.io/react-native/docs/native-modules-android
The other answer pretty much covers the way you implement RN Modules. A useful tip is how to send events to JavaScript, such as below:
private void sendEvent(ReactContext reactContext,
String eventName,
#Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
...
WritableMap params = Arguments.createMap();
...
sendEvent(reactContext, "keyboardWillShow", params);
Further Reading (for your intended feature) for background tasks [ANDROID]
Just to add, you seem like you want to create a background task in React Native. Now from experience, if you want to run something every second - this will work as expected, until the device goes into Doze mode. If you don't want the service to run in the background or Doze mode - that's fine. If so, you may want to start reading about Doze mode and how to test your service in a Doze mode environment.
The issue with background tasks, is that if the phone is idle or stationary - the phone will go into Doze mode. This impacts upon some functionality, such as network. It is expected that if you need to perform actions in Doze mode that you do within a Maintenance Window
Now, I've managed to overcome some issues - by using an Alarm Clock Manager and resetting it to stop Doze mode. However, this does not work in all cases. You'll need a combination of that and a service to keep it alive (but will act differently on a lot of phones). Sometimes the GC just ditches it and kills the process.
Useful links:
Testing your service in Doze mode:
https://developer.android.com/training/monitoring-device-state/doze-standby#testing_doze
Understanding Doze:
https://developer.android.com/training/monitoring-device-state/doze-standby#understand_doze

Realtime checking the progress monitor using Job.getJobManager.IsIdle()

I am trying to continuously check if the progress monitor has an operation that is running in the background.
For this, I used Job.getJobManager.IsIdle().
I have tried the following:
Put it inside a Job.
WorkspaceJob job = new WorkspaceJob("Hello")
{
#Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException
{
while(!Job.getJobManager().isIdle())
{
System.out.println(!Job.getJobManager().isIdle());
}
return Status.OK_STATUS;
}
};
job.setPriority(Job.SHORT);
job.schedule();
But this does not work as Job.getJobManager.isIdle will never return false because Job 'Hello' is running.
Put it inside an asynchronous thread.
new Thread(new Runnable()
{
#Override
public void run()
{
Display.getDefault().asyncExec(new Runnable()
{
#Override
public void run()
{
while(!Job.getJobManager().isIdle())
{
System.out.println("hi");
}
}
});
}
}).start();
But this does not work either as this will freeze the main Eclipse GUI preventing other processes (if there are any existing) to finish.
If anyone has suggestions or any input on how it should be done, it would be great!
You can use a job change listener IJobChangeListener to listen for all changes to job states. You can than test for idle in appropriate places in the listener. Do not try and loop calling isIdle.
You can use the JobChangeAdapter class which provides default implementations of the IJobChangeListener methods so that you only have to override the events you are interested in, probably just the done method:
Job.getJobManager().addJobChangeListener(new JobChangeAdapter()
{
#Override
public void done(IJobChangeEvent event)
{
if (Job.getJobManager().isIdle() {
// Manager is idle
}
}
});

Pass data from android service to ContentPage in Xamarin Form based application

I am having one Application based on XamarinForms.
One background service I have created in Android project and that service would like to send data to ContentPage(which is in PCL) which is displayed to user.
How could I pass data to ContentPage(From xx.Droid project to PCL)?
One solution is:
To Create class in PCL with static variable(e.g. var TEMP_VAR), which will be accessed from xxx.Droid project.
Update value of that static variable(TEMP_VAR) from the service class from the xxx.Droid project.
Need to create Notifier on that static variable(TEMP_VAR)
Update the content page using MessageCenter Mechanism if require.
If there is any better solution, could you please provide me?
This can be achieved using the concept of C#
Dependency service
Event
Need to have 4 classes for such an implementation:
Interface in PCL(e.g. CurrentLocationService.cs) with event handlers defined in it.
namespace NAMESPACE
{
public interface CurrentLocationService
{
void start();
event EventHandler<PositionEventArgs> positionChanged;
}
}
Implementation of interface of PCL in xxx.Droid project (e.g. CurrentLocationService_Android.cs) using Dependency service
class CurrentLocationService_Android : CurrentLocationService
{
public static CurrentLocationService_Android mySelf;
public event EventHandler<PositionEventArgs> positionChanged;
public void start()
{
mySelf = this;
Forms.Context.StartService(new Intent(Forms.Context, typeof(MyService)));
}
public void receivedNewPosition(CustomPosition pos)
{
positionChanged(this, new PositionEventArgs(pos));
}
}
ContentPage in PCL - which will have object of implementation of interface.
Object can be obtained by
public CurrentLocationService LocationService
{
get
{
if(currentLocationService == null)
{
currentLocationService = DependencyService.Get<CurrentLocationService>();
currentLocationService.positionChanged += OnPositionChange;
}
return currentLocationService;
}
}
private void OnPositionChange(object sender, PositionEventArgs e)
{
Debug.WriteLine("Got the update in ContentPage from service ");
}
Background service in xxx.Droid project. This service will have reference of implementation of dependency service CurrentLocationService.cs
[Service]
public class MyService : Service
{
public string TAG = "MyService";
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
Log.Debug(TAG, TAG + " started");
doWork();
return StartCommandResult.Sticky;
}
public void doWork()
{
var t = new Thread(
() =>
{
Log.Debug(TAG, "Doing work");
Thread.Sleep(10000);
Log.Debug(TAG, "Work completed");
if(CurrentLocationService_Android.mySelf != null)
{
CustomPosition pos = new CustomPosition();
pos.update = "Finally value is updated";
CurrentLocationService_Android.mySelf.receivedNewPosition(pos);
}
StopSelf();
});
t.Start();
}
}
Note : PositionEventArgs class need to be created as per usage to pass on data between service and ContentPage.
This works for me like charm.
Hope so this would be helpful to you.