i am making a image downloading android app that takes a certain number of image urls, creates GUI for required for the number of urls provided and then displays them. I succeeded in doing so. Now i am trying to separate a module of this task. In order to do so i want to do everything out of the MainActivity class. The MainActivity class just provides the input in the form of urls and then takes the result back and displays it.
JAVA Code: MainActivity Class:
public class MainActivity extends AppCompatActivity {
ArrayList<String> urls = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addUrls();
}
public void downloadImages(View view){
Manager manager = new Manager(MainActivity.this,urls);
manager.downloadImages();
}
public void addUrls() {
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTXEZRoYOhIJxL5foNz_NlatDlgYStzZgVIiKuo6vtRtz2wY-8b4Q");
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSFL3WYbqNOX-dwjtT1LroBlY5W-3YuwSIuCMRaLpnjMXbVPEJy");
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQiwgrJeAJN-7lcy92N51uP7XzccK_p-fTSJNCXPLPSVih8wqPf");
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT19dYLCEZlMRqojedJB-05jTrflD74nasvkXs-SdVeyM2BEpCSFA");
urls.add("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg");
urls.add("https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg");
urls.add("https://images.unsplash.com/photo-1418489098061-ce87b5dc3aee?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=2f033882f3c25404e3f904fbfe2351be&w=1000&q=80");
urls.add("https://techcrunch.com/wp-content/uploads/2018/03/gettyimages-705351545.jpg?w=730&crop=1");
}
}
Manager class(a class that acts as a manager or GUI making class):
class Manager {
private Context context;
private ArrayList<String> urls = new ArrayList<>();
LinearLayout linearLayoutScrollView;
ImageView imageView;
ProgressBar progressBar;
RelativeLayout relativeLayout;
ImageDownloader imageDownloader;
public Manager(Context context, ArrayList<String> urls) {
this.context = context;
this.urls = urls;
}
public void buildUI() {
System.out.println("Error # 1");
imageView = new ImageView(context);
imageView.setVisibility(View.GONE);
System.out.println("Error # 2");
progressBar = new ProgressBar(context);
progressBar.setIndeterminate(true);
progressBar.setVisibility(View.GONE);
System.out.println("Error # 3");
relativeLayout = new RelativeLayout(context);
relativeLayout.addView(imageView);
relativeLayout.addView(progressBar);
System.out.println("Error # 4");
linearLayoutScrollView = (LinearLayout) findViewById(R.id.linearLayoutScrollView);
linearLayoutScrollView.addView(relativeLayout);
System.out.println("Error # 5");
}
public void downloadImages() {
for (int i = 0; i < urls.size(); i++) {
buildUI();
imageDownloader = new ImageDownloader(imageView,progressBar,imageDownloader);
progressBar.setVisibility(View.VISIBLE);
imageDownloader.execute(urls.get(i));
}
}
}
ImageDownloader Class:
public class ImageDownloader extends AsyncTask<String, Void, Bitmap> {
ImageView imageView;
ProgressBar progressBar;
ImageDownloader imageDownloader;
public ImageDownloader(ImageView imageView, ProgressBar progressBar, ImageDownloader imageDownloader) {
this.imageView = imageView;
this.progressBar = progressBar;
this.imageDownloader = imageDownloader;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
imageView.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected Bitmap doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
System.out.println("Content Type = " + connection.getContentType());
if (connection.getContentType().contains("image")) {
InputStream inputStream = connection.getInputStream();
return BitmapFactory.decodeStream(inputStream);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
try {
imageView.setImageBitmap(bitmap);
progressBar.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
XML Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
tools:context="com.example.syeddanish.downloadingimages.MainActivity">
<LinearLayout
android:id="@+id/buttonsLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<Button
android:id="@+id/downloadImagesButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="downloadImages"
android:text="Download Images" />
<Button
android:id="@+id/resetButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="reset"
android:text="Reset" />
</LinearLayout>
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/buttonsLinearLayout">
<LinearLayout
android:id="@+id/linearLayoutScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</RelativeLayout>
The issue is that in the "Manager"class it gives error to "add qualifier to method" in findViewById()
method.
linearLayoutScrollView = (LinearLayout) findViewById(R.id.linearLayoutScrollView);
And if i add a this qualifier it changes the above line like this
linearLayoutScrollView = (LinearLayout) linearLayoutScrollView.findViewById(R.id.linearLayoutScrollView);
and then gives the error logcat:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.syeddanish.downloadingimages, PID: 29339 java.lang.IllegalStateException: Could not execute method for android:onClick at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293) at android.view.View.performClick(View.java:6291) at android.view.View$PerformClick.run(View.java:24931) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7425) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) at android.view.View.performClick(View.java:6291) at android.view.View$PerformClick.run(View.java:24931) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7425) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.widget.LinearLayout.findViewById(int)' on a null object reference at com.example.syeddanish.downloadingimages.Manager.buildUI(Manager.java:45) at com.example.syeddanish.downloadingimages.Manager.downloadImages(Manager.java:54) at com.example.syeddanish.downloadingimages.MainActivity.downloadImages(MainActivity.java:24) at java.lang.reflect.Method.invoke(Native Method) at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) at android.view.View.performClick(View.java:6291) at android.view.View$PerformClick.run(View.java:24931) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7425) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
please point out what i am doing wrong and what to change to remove this issue.