Victor Victor - 13 days ago 5
Android Question

Troubles importing inner class into main activity on Java (Android)

I'm making an Android app that makes use of AsyncTask to download some data. To make my code a bit more readable I re-created this code on a separate class ("ContentManager"). However, I don't know how to import it into my main activity.

Here's the code on my main activity, which doesn't work (error: "Cannot resolve symbol DownloadJson"):

public class MyApp extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category_list);

ContentManager contentManager = new ContentManager();
ContentManager downloadJsonTask = new contentManager.DownloadJson();

downloadJson.execute("http://.../api/...");

}
}


And here's my AsyncTask code, that lives in a class file (ContentManager.java on the same package folder than the main activity):

public class ContentManager {

// DownloadJson is a class that gets a JSON response given a url specified on the call
public class DownloadJson extends AsyncTask<String,Void,String> {

@Override
protected String doInBackground(String... urls) {

// Defined required variables
String result = "";
URL url;
HttpURLConnection urlConnection = null;

// Try to download content
try {

url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();

InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);

int data = reader.read();

while (data != -1) {

char currentCharacter = (char)data;

result += currentCharacter;

data = reader.read();
}
return result;
}
catch(MalformedURLException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
return null;
}
}
}


How can I import an inner class from another file? Is this the correct way of doing it?

Answer

Ah, i'm old :)

The problem is with your declaration of DownloadJson class. Simply because it is non static inner class.

And as such it requires you to provide outer class reference to create an instance.

So forcing our way to simply create instance is:

DownloadManager dm = new DownloadManager();
dm.new DownloadJson ();
// But this is simply ridiculous right?

The proper way is to add static to your DownloadJson class

public static class DownloadJson extends AsyncTask<String,Void,String> {

And with that usage is much simpler:

DownloadJson json = new ContentManager.DownloadJson();

So the last thing is to say why, and what actually happens :)

There are two ways to declare inner class

1 - Non static

public class A { 
    int value;
    public class B {
    }
}

The B class hold an reference to upper class and as such it needs to be created from class A, or to be created with class A reference (as context), declaring our inner class this ways makes possible to access any non static method, variable or type of upper class as if u would normally in upper class. So writing this code is correct inside B class

void setUpperValue() {
    value = 30; 
}

2 - Static

public class A {
    int value;
    public static class B {
    }
}

The B class hold no reference to upper class and us such does not need any additional context to create however it cannot access to local (non static variables). So invoking inside class B:

value = 20;

Will make compile time error

Comments