我有一个MainActivity
,ActionBar
上有两个标签。我在该活动上的主要布局是空FrameLayout
。第一个标签包含ProgressBar
,第二个标签包含开始下载文件的Button
。这是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;
}
}
和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);
}
}
}
}
}
当我点击 StartDownload Button
时,应用程序崩溃并出现以下异常:
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)
有没有人知道如何在应用的不同部分更改ProgressBar
的进度?
答案 0 :(得分:0)
代码中的主要问题以及NullPointerException
的原因是行:
imagesTab = new ImagesTab();
您实例化新的ImagesTab
Fragment
。问题是这个新Fragment
实例与Activity
(它位于“空中”)无关,因此其getActivity()
方法返回null
。您传递给null
方法的getActivity()
方法中的此Intent
值会在downloadStarted()
方法中构建NulPointerException
方法。不要像你那样实例化ImgesTab
,而应该通过使用getFragmentManager()
并基于其标签搜索片段来获取对父活动中已经(很可能)的另一个片段的引用
其次,更新ProgressBar
似乎更像是一个应用程序设计问题。例如,为什么在选项卡中有Button
开始下载,而在另一个选项卡中有ProgressBar
显示下载进度?此外,您似乎使用Service
进行下载,因此您应该真正使Service
下载文件和所需的标签片段(使用ProgressBar
,而不是让标签进行通信。沟通。通过在某些下载级别将Service
发送到发送广播并使Activity
(包含两个选项卡片段)动态注册BroadcastReceiver
,可以非常简单。当Service
发送广播时(例如10%),Activity
的{{1}}将会提取(如果它还活着),然后它会更新{{1}如果BroadcastReceiver
在那一刻可见,则从期望的ProgressBar
开始。