Android 在另一个类的ProgressBar上设置进度

Android 在另一个类的ProgressBar上设置进度,android,nullpointerexception,android-fragments,progress-bar,android-tabs,Android,Nullpointerexception,Android Fragments,Progress Bar,Android Tabs,我有一个MainActivity,它在ActionBar上有两个选项卡。我在该活动上的主要布局是一个空的FrameLayout。第一个选项卡包含一个ProgressBar,第二个选项卡具有开始下载文件的按钮。下面是设置选项卡: public class SettingsTab extends Fragment { private Button downloadButton; private ImagesTab imagesTab; private static Strin

我有一个
MainActivity
,它在
ActionBar
上有两个选项卡。我在该活动上的主要布局是一个空的
FrameLayout
。第一个选项卡包含一个
ProgressBar
,第二个选项卡具有开始下载文件的
按钮。下面是
设置选项卡

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;

    }
}
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);
                }
            }
        }
    }
}
当我单击StartDownload
按钮时,应用程序崩溃,出现以下异常:

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)
11-26 03:55:55.765:E/AndroidRuntime(21200):致命异常:main
11-26 03:55:55.765:E/AndroidRuntime(21200):java.lang.NullPointerException
11-2603:55:55.765:E/AndroidRuntime(21200):位于android.content.ComponentName.(ComponentName.java:75)
11-2603:55:55.765:E/AndroidRuntime(21200):在android.content.Intent.(Intent.java:3227)
11-26 03:55:55.765:E/AndroidRuntime(21200):在com.example.lista2.ImagesTab.downloadStarted(ImagesTab.java:32)
11-26 03:55:55.765:E/AndroidRuntime(21200):在com.example.lista2.SettingsTab.downloadImages(SettingsTab.java:55)
11-26 03:55:55.765:E/AndroidRuntime(21200):在com.example.lista2.SettingsTab$1.onClick(SettingsTab.java:72)

是否有人知道如何在应用程序的不同部分更改中的
ProgressBar的进度?

代码中的主要问题,导致
NullPointerException
的原因如下:

imagesTab = new ImagesTab();
在这里实例化一个新的
ImagesTab
片段
。问题是这个新的
片段
实例没有绑定到
活动
(它在“空中”),因此它的
getActivity()
方法返回
null
。此
null
值来自传递给
Intent
getActivity()
方法,该方法在
downloadStarted()
方法中生成,该方法将抛出
NulPointerException
。不要像您那样实例化
ImgesTab
,您应该通过使用
getFragmentManager()
并根据其标记搜索片段,获得对父活动中已经(很可能)的其他片段的引用

其次,更新
ProgressBar
似乎更像是一个应用程序设计问题。例如,为什么在一个选项卡中有启动下载的
按钮
,在另一个选项卡中有显示下载进度的
进度条
?此外,您似乎使用
服务
进行下载,因此,您不应该让选项卡通信,而应该让下载文件的
服务
与所需的选项卡片段(使用
进度条
)通信。通过将
服务
设置为特定下载级别的发送广播,并使您的
活动
(包含两个选项卡片段)动态注册
广播接收器
,可以非常简单地实现这一点。当
服务
发送广播(例如10%)时,
活动
广播接收器
将拾取它(如果它是活动的),然后它将从所需的
片段
更新
进度条
,如果此时该
片段
可见