Android class with nested asynctask - java

I am relatively new (ish) to Java..
I am writing an Android app, and now I am going back over my code and tidying up and adhering my coding structure to a more best practice style.
I am building methods and classes as I see fit to avoid the numerous amounts of duplicate code that I have produced. I have found myself trying to create a class (e.g. HeavyStuff.java) that contains several AsyncTask methods inside it (e.g. MyTask1 and MyTask2). When calling the class from an activity, I'd like to execute MyTask1 at some point, and at some point elsewhere I'd like to execute MyTask2. I am trying to use the following respectively:
HeavyStuff.MyTask1 myTask1 = new HeavyStuff.MyTask1();
myTask1.execute();
And
HeavyStuff.MyTask2 myTask2 = new HeavyStuff.MyTask2();
myTask2.execute();
The problem is, I get an error saying that "HeavyTest is not an enclosing class". My class looks like this:
package com.wizzkidd.myapp;
import android.os.AsyncTask;
public class HeavyStuff {
public class MyTask1 extends AsyncTask<String, String, String> {
//...
//...
}
public class MyTask2 extends AsyncTask<String, String, String> {
//...
//...
}
}
The class can also be seen here in full: http://hastebin.com/yahihokupu
What am I missing that is required to make the class an "enclosing class".
-----EDIT-----
I've looked at the answer that was given as a possible duplicate to my question and it does not work. The answer given recommends using static for my inner class, but this doesn't work for me.
I have however found that I can do this:
HeavyStuff.MyTask1 myTask1 = new HeavyStuff().new MyTask1();
myTask1.execute();
It works, but what are the implications (if any) when doing it like this? Is it bad practice?

I understand that you put both MyTask1 and MyTask2 into the same class because they are similar, however in general this is not ideal.
If you plan on creating new instances of MyTask1 and also new instances of MyTask2 throughout your code base, then they should be in their own completely separate classes (i.e. MyTask1.java containing only class MyTask1).
You can still keep them "together" by putting them within the same java package, for example:
package.heavystuff
.

I have found an answer to my question. I originally posted what I believe is a solution as an edit, but to clarify, this is my working answer:
HeavyStuff.MyTask1 myTask1 = new HeavyStuff().new MyTask1();
myTask1.execute();

Related

How can one use ScalaTest in a Java test file?

It is possible to use ScalaTest in a Java test file, and if so where can I find examples?
When I try something like:
// MyUTest.java
import org.scalatest.flatspec.AnyFlatSpec;
import org.scalatest.matchers.should.Matchers;
public class MyUTest extends AnyFlatSpec, Matchers {
...
}
I get an error that equal(Object) in Matchers clashes with the same method in matchers.dsl.MatherWords
TL;DR: You cannot do what you are trying.
As stated in Using Scala traits with implemented methods in Java:
From Java perspective Trait.scala is compiled into Trait interface. Hence implementing Trait in Java is interpreted as implementing an interface - which makes your error messages obvious. Short answer: you can't take advantage of trait implementations in Java, because this would enable multiple inheritance in Java (!)
and Matchers is a trait. However, to overcome this issue, you can just remove the Matchers extension, and have the test class:
import org.scalatest.flatspec.AnyFlatSpec;
public class MyUTest extends AnyFlatSpec {
}
Which will compile. Having said that, it will be really hard to actually use the the ScalaTest functionality in Java. For example, a simple test class will be:
public class MyUTest extends AnyFlatSpec {
it should "test1" in { println("test1") }
}
The word should above, is declared at AnyFlatSpecLike, which is trait as well. So you cannot really use it. So I am not really sure how you can overcome this issue, as this is the very basic example that you can find in ScalaTest quick start.
After the above analysis, I think it's going to be really difficult to use ScalaTest in Java. What you can easily do, is the other way around. If you already support Scala, and you have ScalaTest, you can just test the java code in Scala. It is a bit less "organized" as you'd expect to see the java test classes under the java folder, which we just proved impossible. I think having this "mess" is the best solution in such structure.
I totally agree with #Tomer Shetah. I would like to add that you can create wrapper for java on scala:
class JavaScalaTestWrapper extends AnyFunSpec with Matchers {
def println(x : scala.Any) = Predef.println(x)
def shouldEqual(x : scala.Int, ) = SomeCode.someFunc(x) shouldBe s"${x}"
}
And after that you can extend all java test classes through this wrapper:
public class SomeOperationTestJava extends JavaScalaTestWrapper {
#Test
void someOperation() {
SomeOperation so = new SomeOperation();
println("=== test ===");
assert(("test").equals(so.someOperation()));
shouldEqual(3);
}
}
And all scala styled code you can put in wrapper, and after that use these methods from original java code, like additional workaround.

How to know dynamically if the loaded class is application class?

I am in a situation that I want to do some rewriting on loaded,i.e., currently running application class. I do not want to rewrite loaded library class. Thus I need to sort of filter the rewriting based either on the type of the class, being application or none application class, or another way I could do it is by checking the ClassLoader and see if it is of Application Class type.
To give some context let's assume I have the following code
URLClassLoader urlcl = new URLClassLoader(cp);
Class c = urlcl.loadClass(_className);
Assuming that _className is the current running class, that was intercepted by a listener, how can I know if this class c is an application class or not?
Much appreciated!
I'm not entirely sure of what do you mean by application class, but those hints still might be helpful.
You can simply check if one class is subtype of another with:
public static boolean is1stSubTypeOf2nd(Class clazz1, Class clazz2) {
return clazz2.isAssignableFrom(clazz1);
}
If you would like to check if the class belongs to some package (to check if it is the class from standard API, third party library or not), you can use:
public static boolean isInPackage(Class clazz, String packageName) {
return clazz.getPackageName().contains(packageName);
}
Further the standard API is able to provide you an info about all super classes of given class.

Why can't classes that use EJB #Schedule be abstract Classes?

I need to schedule a task and I'm using EJB #Schedule to do so. It's working fine, however I thought I might try to generalize my design so that I can extend from some abstract scheduler, inherit certain functionality, and specify additional functionality in the sub classes extending the abstract class. This way, when I need additional schedulers that perform similar actions, I don't have to rewrite a bunch of code. I wrote it, didn't get any errors, and I thought all was well, and then when I tried to restart my server,
I got:
EJB class com.schedule.SubmissionScheduler must not be defined as abstract : mcftEAR#mcftWeb.war#SubmissionSchedule in the console.
Maybe I don't know enough about how the #Schedule annotation works, but I can't think of any reason abstract classes won't be allowed for this. Any insight would be appreciated
import java.util.List;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
public abstract class SubmissionScheduler {
public abstract SubmissionScheduler getInstance();
#Schedule(hour= "0")
public void every24Hours() {
// Pull all forms and submit every 24 hours
List<Form> forms = getFormsThatAreReadyForSubmission();
// Loop through the list of forms and submit
if (forms != null || !forms.isEmpty()) {
for (Form form : forms) {
form.getFormDao().submit());
}
}
}
...Then I have another class which extends this one.
EDIT: In addition to not being able to make it an abstract class, it won't allow for the class to be final either...Why??
Basically you need an instance of your bean to run any function - in your case scheduled function.
It is impossible to run a function from abstract class cause it's abstract - a container cannot create instance to run your code. So it have to be non abstract to create instance and run a method.

GsonRequest class is a List

I am currently making a GsonRequest as follows:
final GsonRequest gsonRequest =
new GsonRequest(url, People.class, null, new Response.Listener<People>() { ... }
But my People class has only one member object: List of Person(s).
public class People {
private List<Person> people;
}
I did it like because the argument for the GsonRequest called for a class (i.e., People.class). To me it seems strange and silly to make a class that only has one member object which is just a list of another objects. But the request I am making will return multiple Person(s). So, is there a better way? Can I pass a List of objects instead of a made up class like I did? My way is working, but I can't help but think there is a better way???
You can define it like this:
public class People extends List<Person> {
}
And that will work, at least you aren't defining a one-member class (you also need to make API change to match).
If you want to avoid the class completely, you can also use TypeToken<E>:
new TypeToken<List<Person>>(){}.getType()
However your GsonRequest class must be able to accept a Type instead of a class parameter.

Understanding generic Java class signature in cross compilation with C#

I have to implement some classes in Java that will pass tests written in C# (using Visual Studio unit tests). I came across problem with this part of test:
var portfolioSignatureAttribute = dllType
.GetCustomAttributes(typeof(SignatureAttribute), false)
.Cast<SignatureAttribute>()
.FirstOrDefault();
Assert.AreEqual("<C::LIConverter<LCurrency;LCurrency;>;>Ljava/util/ArrayList<LBoughtStock;>;Ljava/lang/Iterable<LBoughtStock;>;", portfolioSignatureAttribute.Signature, iterableMessage);
The signature I tried writing was, but doesn't work is:
public class Portfolio extends ArrayList<BoughtStock> implements IConverter<Currency, Currency>, Iterable<BoughtStock>
Also, i got some message thrown by this assertion:
Type Portfolio incorrect signature. Remember to add generic interface java.lang.Iterable implementation. Remember to give a name C to generic parameter. Remember also to inherit your class from java.util.ArrayList.
And here is also fragment from test output:
Result Message: Assert.AreEqual failed.
Expected:<<C::LIConverter<LCurrency;LCurrency;>;>Ljava/util/ArrayList<LBoughtStock;>;Ljava/lang/Iterable<LBoughtStock;>;>.
Actual:<Ljava/util/ArrayList<LBoughtStock;>;LIConverter<LCurrency;LCurrency;>;Ljava/lang/Iterable<LBoughtStock;>;>.
So generally, there is problem with: lack of "C::" and with order of those attributes. I totally cannot find anywhere any informations about such things, and how to understand it. And the question is - what the class signature should be?
Thanks for help!
I managed to solve the problem (by myself, i am proud :) )
The signature should be:
public class Portfolio<C extends IConverter<Currency, Currency>> extends ArrayList<BoughtStock> implements Iterable<BoughtStock> {

Categories

Resources