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%)时,活动
的广播接收器
将拾取它(如果它是活动的),然后它将从所需的片段
更新进度条
,如果此时该片段
可见