How to create a background task in IntelliJ plugin

Hi
I'm developing an IntelliJ-idea plugin and want to run code that automatically install and deploy the maven modules using command line in background task without blocking the UI (visible in the background tasks dialog and in another thread than the UI).
I found the following Helper class and tried it by passing a Runnable object and implement its run method but it still blocking the UI and when I tried to do the threading myself i got the following error:
 
Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())
     Details: Current thread: Thread[Thread-69 [WriteAccessToken],6,Idea Thread Group] 532224832
     Our dispatch thread:Thread[AWT-EventQueue-1 12.1.4#IU-129.713, eap:false,6,Idea Thread Group] 324031064
     SystemEventQueueThread: Thread[AWT-EventQueue-1 12.1.4#IU-129.713, eap:false,6,Idea Thread Group] 324031064

0

The error message you've posted tells you exactly what you need to do in order to fix the problem.

0
Avatar
Permanently deleted user

I already used this solution using the following class
https://github.com/inmite/android-selector-chapek/blob/master/src/utils/RunnableHelper.java

i.e.

ApplicationManager.getApplication().runReadAction(cmd);

but when i tried this solution the UI is blocked untill the process is finished, it didn't do it in background thead

0

Please see http://confluence.jetbrains.com/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview. This explains what a read action is and how to initiate it properly.

0
Avatar
Permanently deleted user

I have tried the same code in the link as the following

ApplicationManager.getApplication().runReadAction(new InstallRunnable(project));
also
ApplicationManager.getApplication().invokeLater(new InstallRunnable(project), ModalityState.any().NON_MODAL);



and here is the InstallRunnable class:


public class InstallRunnable implements Runnable {


    private Project project;


    public InstallRunnable(Project project){
        this. project = project;
    }


    @Override
    public void run() {
        ModuleManager moduleManager = ModuleManager.getInstance(project);
        Module[] modules = moduleManager.getModules();


        for (Module module : modules) {
            // do $mvn install here for each module
        }


    }
}



I really can't know what I'm missing here !!!
0

You need to use both invokeLater() and runReadAction().

0
Avatar
Permanently deleted user

Hi Dmitry,

Can you tell me an example or code snipt because I have tried a lot of compinations and still no thing works with me

Thanks in advance,
Mahmoud

0

ApplicationManager.getApplication().invokeLater(new Runnable() {
  public void run() {
    ApplicationManager.getApplication().runReadAction(new Runnable() {
      public void run() {
        // do whatever you need to do
      }
    });
  }
});

0
Avatar
Permanently deleted user

I did the same code you posted as the following

Calling:

ApplicationManager.getApplication().invokeLater(new Runnable() {
            public void run() {
                ApplicationManager.getApplication().runReadAction(new InstallRunnable(project));
            }
        });




InstallRunnable Class:

public class InstallRunnable implements Runnable {
    private Project project;
    public InstallRunnable(Project project){
        this.project = project;
    }


    @Override
    public void run() {
         ModuleManager moduleManager = ModuleManager.getInstance(project);
        Module[] modules = moduleManager.getModules();


        for (Module module : modules) {
           // do Install each module
        }


    }
}

still the UI is blocked while the code in running, what is the problem with my code???

0

Sorry, instead of invokeLater() you need to use executeOnPooledThread().

0
Avatar
Permanently deleted user

Thanks it works now :)

1

Thank you, helped me too!

0

If I need to perform an update to the UI and I want it to be non-blocking it looks like I have to use a

Task.Backgroundable

but I'm in a Settings plugin and I'm not sure that makes sense since it requires a project. Any thoughts? My plugin has a "test connection" button that I want to run the test in the background and not block the UI and then write to the UI if it was a success or failure. 

I added a question on SO with more context

Question 66790332

@... thoughts?

0

请先登录再写评论。