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
请先登录再写评论。
The error message you've posted tells you exactly what you need to do in order to fix the problem.
I already used this solution using the following class
https://github.com/inmite/android-selector-chapek/blob/master/src/utils/RunnableHelper.java
i.e.
but when i tried this solution the UI is blocked untill the process is finished, it didn't do it in background thead
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.
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 !!!
You need to use both invokeLater() and runReadAction().
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
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
// do whatever you need to do
}
});
}
});
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???
Sorry, instead of invokeLater() you need to use executeOnPooledThread().
Thanks it works now :)
Thank you, helped me too!
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
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?