Repository navigation
New BackgroundExecutor is failing in my app #625
Description
Activity
I was just about to come and add one for this. Here is my situation, I have a library project and an android app project. The library project has some base classes for Activities in it, so now when I use the @background annotation in the library project it will create an org.androidannotations.api.BackgroundExecutor class in the library project, when I use the @background annotation in the android app project, it creates the same class as well. This causes the application to fail when deploying because there are multiple of this class.
@rockytriton > yep this is another issue I noticed the other day. After the package renaming it appears that some classes of API project are copied in developer project... Which isn't the right way to do it because theses classes are already in the API jar which is in the classpath. I opened the issue #626 about that.
@rom1v > Do you have any idea about the issue on BackgroundExecutor ?
What's strange is the org.androidannotations.api.BackgroundExecutor class is not in the API jar file, it's only in the main jar, so it doesn't complain when it does this on a normal android project but if the project uses a library project then you have a duplicate.
I think the cause is exactly the issue #626 you just opened.
I already had this problem with Eclipse, I don't remember exactly what to do to solve it, but I think restarting eclipse was sufficient ( + project clean?).If it is the same problem as I had, this is not specifically related to
BackgroundExecutor: it happens whenever you make changes in the java files which are copied into your project by AA (without restarting Eclipse).About @rockytriton duplicate: if
@Backgroundis used in project and a dependant library, there should be no difference between oldBackgroundExecutorand the new one. Both should work or both should fail. Could you test with version 2323d7a please?@rom1v this isn't an issue with cleaning and rebuilding a project, at least not in my case where I have an android project which uses a library project and both are using the @background annotation. In that case you get 2 actual copies of the BackgroundExecutor, one in the library project jar and one in the android app.
I think I read a bit too fast your problems and I confused with #626 message…
@romainpiel Do you set an executor manually somewhere (
BackgroundExecutor.setExecutor(…))? And when you talk about threads, do you mean exclusively@Backgroundannotated method calls?@rockytriton Could you test with version 2323d7a please (to decide whether it is related to pull #569 or not)?
Nope, not using set executor anywhere. I'm using the
@Backgroundannotation andBackgroundExecutor.execute(). (Sorry I'm on my phone)@romainpiel The executor has a fixed number of threads.
If you submit more tasks than this threshold, then your tasks will be blocked until previous ones have completed execution.Before pull request #569,
Executorimplementation wasExecutors.newCachedThreadPool(), so your threads were not blocked above a threshold.But you should not rely on this unspecified behaviour: if you need to start a lot of long-running threads, then you must set your own
Executorto ensure the behaviour:BackgroundExecutor.setExecutor(Executors.newCachedThreadPool());
I'll see if I can come up with a small test using that version, but I'm pretty sure that pull #569 isn't the problem, the code
holder.generateApiClass(element, BackgroundExecutor.class);
is what is putting that BackgroundExecutor class in each project's generated code section. I think that this class should just be moved into the API jar instead of being in the main jar and then "generated" into the project.
@rom1v oh I see! would it be a good idea to have two separate executors, one for the long running operations and the default one for all other operations?
UPDATE: I upgraded to latest version of the snapshot and using a separate executor for my long running operations seems to work. Not sure if it's a good practice though.
I think what you really needs here is an Android service and not
@Backgroundannotated methods.Well a service will run on the main thread so that's out of question. I'm basically launching these long running operations in separate threads from a service. The thing I'm not sure is wether an app can have multiple executors each with different strategies.
oh I see! would it be a good idea to have two separate executors, one for the long running operations and the default one for all other operations?
There is no reason to hardcode 2 separators (one for long-running, one for the others), this separation is arbitrary and project-specific.
We could imagine adding an executor id to@Background, to manually setting an executor for every id used by the application, but it would add unecessarily complexity to@Background.Moreover, if you don't need to delay background tasks, once you have your cached thread pool, why don't you use it even for "normal" background tasks?
By the way,
AsyncTaskuses a limited number of threads too (10 before Honeycomb, only 1 now).Try:
final AtomicInteger integer = new AtomicInteger(); for (int i = 0; i < 20; i++) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... dummy) { SystemClock.sleep(2000); System.out.println(integer.incrementAndGet()); return null; } }.execute(); }
I just got used to use this annotation but your right, a simple AsyncTask would do the job. I'll have a look at that too. Well thanks for your help guys, I guess the issue can be closed now.
a simple AsyncTask would do the job
What I said is that, on the contrary, you will have the same "problem" with an
AsyncTask.Ok so you're saying a separate executor would do the job then?
If you don't use
delayattribute of@Backgroundannotation, I suggest you just set your own executor:BackgroundExecutor.setExecutor(Executors.newCachedThreadPool());
But I don't know exactly what your needs are…
no worry I'll figure it out. thanks! 👍
Could you test again with the latest version of AA ?
@DayS was that one for me? Sure I can give it a go. What should I test?
I just tested with the latest codebase, if I turn on AA for both the android library project and the android app project then they will both still create a BackgroundExecutor.java class which causes the dalvik compiler to fail. This happens if my library project and android project both have an Activity that uses the @background annotation.
By the way, I played around with a fix for this and was able to get it to work by moving the BackgroundExecutor class to the api jar and removing the section of code which generates the java file from the processor jar, it appeared to work properly.
You should have the exact same issue with
SdkVersionHelperwhich is generated while usingEActivity, andViewServerif you're enabling support of hierarchy viewer in both project.Since my PR #654, only these three classes are generated anymore. I'm not sure this feature is still useful, so...
I don't have any issue using EActivity in lib and app projects. I haven't noticed those classes being generated though so I'm probably just not using that feature.
Just saw that
SdkVersionHelperis only generated ifonBackPressedmethod is overrided by the developer or byFragmentActivity(because we only check that method is not present in anActivityclass)This should be fixed. Please re-open if you're stuck again with this.
Hey guys,
Following latest pull update on Maven 3.0 snapshot I've got an issue in my app related to the new BackgroundExecutor (from pull #569).
I'm sorry I can't explain much what it is, I need to dig a bit more but basically I've noticed new Threads are not launched after a while. I noticed this happens after I launch a few blocking operations inside new threads. These operations are publish/subscribe calls and can remains there for a few minutes. From the point I start a few of these calls, it seems that other background tasks are not launched.
Sorry I know this is not precise at all. I'll try to debug a bit more and see what's happening there. I'll stick with the previous snapshot for now.