"...MovieDetail is not an enclosing class" error on Android - android

I have an activity with two AsyncTasks defined. While building out a two pane tablet UI I moved a lot of the logic to a fragment class. The AsyncTasks are still in the original activity class. I am trying to instantiate and execute the tasks using the qualified names but get a ..is not an enclosing class error. I am instantiating the tasks like so:
MovieDetail.FetchTrailersTask fetchTrailersTask = new MovieDetail.FetchTrailersTask();
I've also tried getActivity.new [package_name].MovieDetail.FetchTrailersTask();
This didn't work either.

I solved this by moving the AsyncTasks to the fragment class. I don't think there was a reason to, but in the event I wanted/needed to leave them in the activity class, I couldn't find a way to do so.

Related

Activity without UI to write a maintainable code

What is the use of Activity without UI? I have a MainActivity where I feel the code is too long and I was thinking about possibly creating a separate Activity without UI for each task and call it in my Main Activity (or use a Headless Fragment maybe?) in order to keep my code maintainable. Is that a bad approach? How do you manage relatively long code in one Activity?
That's a bad idea. It makes sense to break an activity up into multiple classes if its too large/too complicated. If those pieces have a UI, that's basically a fragment. If they don't, they should be some other class. But there's no reason to make them Activities- they're just classes.
THere's very few places where it makes sense to have a headless Activity. Almost all of those places are where Android requires you to start a context but you're not sure which one to start up yet (for example a headless activity that does url routing that's too complex to put into the manifest).
There a lot of things wrong with your questions.
First... An Activity without UI, then doestn need to be an Activity.
Second, you must know what is a class and why we use classs.
Third, When you have long code, maybe your logic is bad, you can separate en in other class the code, example: Adapters, Helpers, Task, etc.... the same activity and code must give you and idea how separte correctly if you know the concepts, please, maybe if you post the code we can help you more.

Where should AsyncTask be?

I am new to android programming. I would like to get some advices about AsyncTask. I have created a main activity and one fragment in which i will display content. The use for AsyncTask in my program is to download data from internet. So, the question would be: where it should be? In the fragment's class or activity's?
You have three choices:
You can make it an inner class inside of the Fragment. This is probably OK if this asynchronous task is only specific to the fragment and you won't ever reuse it
You can make it an inner class inside of the Activity. The is better if you have one activity that controls many Fragments that may reuse the same asynchronous task.
You can make it a class of its own if you plan to reuse it in man places in your application or even if you just want it neater. If you do plan on reusing it but the places that are reusing it may need some slight differences, then you might want to abstract it to make it flexible.
Hope that helps.

Android, parameterization of an AsyncTask with Activity function

I have a small problem in my own android app. I have one class that extends AsyncTask, where in onPostExecute I want to call some method of the Activity from within this task was called. But the problem is that I want three different instances (and maybe some day more) of this task, each of them I want to call different method on my Activity (but all of these methods have the same list of arguments, for now). Is there any elegant way to solve it? Or I just have to create three different classes that differ in one line - name of the calling method in onPostExecute?
I heard that in Java we cannot pass function handle as a paremeter, so it seems really hard. Can anyone help?
I think you should create interface (which contain method with needed arguments), create in Activity three inner classes implementing this interface and pass instance of appropriate class to AsyncTask via contructor.

android cross activity interfaces

Say I have two active activities, A (has a window) and B (has a view embedded in A, but is still it's own activity).
The activities are in different packages but running in the same process.
A view in activity B is added to a view in A that implements an interface I. The declaration of I is in a library shared between A and B.
So I would assume that I could do something along the lines of this inside of an instance of B:
viewInA = viewInB.getParent();
(I)viewInA;
But I get a casting error. Is there a way to make this work?
Doing a bit of introspection can easily prove that viewInA does in fact implement I. The package that I resides in is, of course, the same for both activities.
My set of restrictions due to the situation is rather unique; Doing simple message passing with intents won't work.
I could create a wrapper that uses introspection to get the Methods on the view that I know exist. But that's ugly and I'm lazy.
Everything else aside, if you get a casting error in Java, it's because viewInA does in fact not implement I. Be aware that getParent() returns a class implementing ViewParent... (i.e. does I extend ViewParent??)
Nonetheless, you can set a breakpoint, and check at runtime what type viewInA has!

If AsyncTask is not an inner class... - some questions

1) I don't underestand why the samples of Android almost use AsyncTasks as private inner classes. I know it is convenient to make it inner class but it makes our class file longer and hard to read. ShelvesActivity of Shelves sample application have even 845 lines. Don't you think it is a bad design or bad construction?
2) If I make my ScanStorageTask external class, what do I have to pass to it? entire Activity or only used widgets?
Example: If I must use a WebView, a Button and a ProgressBar in ScanStorageTask.
I use this:
ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it.
or this:
ScanStorageTask task = new ScanStorageTask(webView, button, progressBar);
There's nothing wrong with doing it externally, and it actually might be a better design. Passing UI elements around is the kind of tight coupling that can get you into trouble when you have a really large code base anyway.
Why not do it externally and use the "listener" pattern that the UI controls employ? Make your ScanStorageTask its own class, create an OnCompleteListener interface with an onComplete method, and pass that to your ScanStorageTask instance (expose a setOnCompleteListener method or something to that effect). Then, onPostExecute can just do this:
if(onCompleteListener != null)
onCompleteListener.onComplete(data);
That way, you define your UI updates inside your activity based on the data. It's better separation of concerns and will keep your lines of code per class down, as that seems to be what you'd prefer. If you don't already have this, make a class that represents the data you need to pass in and get out, and that's what you pass in to the task as a param to the execute method and what onPostExecute passes to onComplete.
Inner classes allow you to manipulate the UI of an outer Activity inside onPreExecute(), onPostExecute() and onProgressUpdate() without passing the whole UI structure(s) to the AsyncTask. You are just able to use the activites functions for that.
This is useful since manipulating the UI isn't the main purpose of an AsyncTask. It's doing non-UI background work. And for that, what you usually have to pass is some arguments to do this job (e.g. supplying a URL to download a file).
When you declare your AsyncTask external, you basically can't access your UIs resources inside onPreExecute() (no arguments are passed to this at all), and very hard inside the other two UI functions.
I'd say AsyncTask is just made for beeing used as an inner class to do work and update the UI-thread. See the description:
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
(from the class documentation)
I had the same problem in may application. I wanted to establish a communitation with a PC using a Socket and I wanted my code to be reusable from several Activities/Fragments.
In the first place I tried not to use an inner class but it is very convenient when you have to update the UI so I found an alternative solution :
I created an outer AsyncTask class wich in charge to communicate with the pc and I created inner classes in each of my activites/fragments with only an override of the onPostExecute() method. this way I can reuse my code AND update the UI.
If you just want to get the result of the task and if responsiveness is not essential for your application, you can use the get() method of the AsyncTask class.
Personally I belive that if you use class only at one point, then it's most readable to also define it there - hence the anon inner class.
It does not matter. From design perspective I'd only pass data that is actually needed. However you need to be aware on one possible pitfall - when activity instance gets deactivated (hidden or orientation changed) and your background thread still runs and tries to show some changes, then you can get various errors or nothing s shown at all.

Categories

Resources