Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set progress on ProgressBar in another class

I've got a MainActivity which has two tabs on ActionBar. My main layout on that activity is an empty FrameLayout. The first tab contains a ProgressBar, the second has Button that starts downloading files. Here's SettingsTab:

public class SettingsTab extends Fragment {
    private Button downloadButton;
    private ImagesTab imagesTab;
    private static String fileDir = "sdcard/AndroidCourse/";
    public void downloadImages(String url,int limit,String imageExtension)
    {

        try {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .build());
            Document doc = Jsoup.connect(url).get();
            StringBuilder sb = new StringBuilder("img[src$=.");
            sb.append(imageExtension);
            sb.append("]");
            Elements images = doc.select(sb.toString());
            ArrayList<String> urls = new ArrayList<String>();
            for(Element image : images) {
                if(urls.size() == limit) {  
                    break;
                }
                urls.add(image.attr("src"));
            }
            Log.e("urls", String.valueOf(urls.size()));
            imagesTab.downloadStarted(urls);


        } catch (IOException e) {
            Log.e("SettingsTab", e.getMessage());
        }
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.settings_tab, null);
        downloadButton = (Button) view.findViewById(R.id.startButton);
        imagesTab = new ImagesTab();
        downloadButton.setOnClickListener( new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                downloadImages("http://www.google.com",5,"jpg");


            }

        });
        return view;

    }
}

and ImagesTab:

public class ImagesTab extends Fragment {
    ProgressBar downloadProgressBar;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.images_tab, null);
        downloadProgressBar = (ProgressBar) view.findViewById(R.id.downloadProgressBar);
        //downloadProgressBar.setVisibility(View.INVISIBLE);

        return view;

    }
    public void downloadStarted(ArrayList<String> urls)
    {
        //downloadProgressBar.setVisibility(View.VISIBLE);
        Intent intent = new Intent(getActivity(), DownloadService.class);
        intent.putExtra("urls", urls);
        intent.putExtra("receiver", new DownloadReceiver(new Handler()));
        getActivity().startService(intent);
        Toast.makeText(getActivity(), "Service started!" + urls.size(), Toast.LENGTH_SHORT).show();
    }
    private class DownloadReceiver extends ResultReceiver{
        public DownloadReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            super.onReceiveResult(resultCode, resultData);
            if (resultCode == DownloadService.UPDATE_PROGRESS) {
                int progress = resultData.getInt("progress");
                downloadProgressBar.setProgress(progress);
                if (progress == 100) {
                    downloadProgressBar.setVisibility(View.INVISIBLE);
                }
            }
        }
    }
}

When I click the StartDownload Button, the application crashes with the following exception:

11-26 03:55:55.765: E/AndroidRuntime(21200): FATAL EXCEPTION: main
11-26 03:55:55.765: E/AndroidRuntime(21200): java.lang.NullPointerException
11-26 03:55:55.765: E/AndroidRuntime(21200):    at android.content.ComponentName.<init>(ComponentName.java:75)
11-26 03:55:55.765: E/AndroidRuntime(21200):    at android.content.Intent.<init>(Intent.java:3227)
11-26 03:55:55.765: E/AndroidRuntime(21200):    at com.example.lista2.ImagesTab.downloadStarted(ImagesTab.java:32)
11-26 03:55:55.765: E/AndroidRuntime(21200):    at com.example.lista2.SettingsTab.downloadImages(SettingsTab.java:55)
11-26 03:55:55.765: E/AndroidRuntime(21200):    at com.example.lista2.SettingsTab$1.onClick(SettingsTab.java:72)

Does anyone have an idea how to change the progress of a ProgressBar in on different part of app?

like image 642
Xter Avatar asked Jul 27 '26 19:07

Xter


1 Answers

The main problem in your code, and the reason for that NullPointerException is the line:

imagesTab = new ImagesTab();

where you instantiate a new ImagesTab Fragment. The problem is this new Fragment instance isn't tied to an Activity(it's in the "air") so its getActivity() method returns null. This null value from the getActivity() method you pass to the Intent that you build in the downloadStarted() method which will throw the NulPointerException. Instead of instantiating the ImgesTab like you do, you should get a reference to the other fragment which is already(most likely) in the parent activity by using the getFragmentManager() and searching for the fragment based on its tag.

Second, updating the ProgressBar seems more of a app design problem. For example, why do you have the Button that starts the download in a tab and the ProgressBar which shows the download progress in another tab? Also, you seem to use a Service for the download, so instead of making the tabs communicating you should really make the Service that downloads the files and the desired tab fragment(with the ProgressBar) communicate. This could be made very simple by making the Service to a send broadcast at certain download levels and making your Activity(which holds the two tabs fragments) dynamically registering a BroadcastReceiver. When the Service sends a broadcast(for example at 10%), the Activity's BroadcastReceiver will pick it up(if it's alive) and then it will update the ProgressBar from the desired Fragment if that Fragment is visible at that moment.

like image 188
user Avatar answered Jul 30 '26 09:07

user



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!