我在MainActivity中有一个Fragment Home.java,它有查看寻呼机图像。我已经使用计时器来安排在此viewpager中自动滑动图像。每当我点击设备上的后退按钮退出应用程序时,我都会得到一个NULL指针异常。这是我的代码
public class Home extends Fragment {
Timer timer ; //Timer variable
int page = -1; //Page starts at zero.
int page1 = 8; //Number of images there are
int flag = 0;
int y =0;
ImageLoader imageLoader;
DisplayImageOptions options;
//Images to be displayed on top
String[] imageUrls = new String [] {
"https://lh3.googleusercontent.com/-JB9v6rtgHhk/URqup21F-zI/AAAAAAAAAbs/64Fb8qMZWXk/s1024/Golden%252520Grass.jpg",
"https://lh4.googleusercontent.com/-EIBGfnuLtII/URquqVHwaRI/AAAAAAAAAbs/FA4McV2u8VE/s1024/Grand%252520Teton.jpg",
"https://lh4.googleusercontent.com/-WoMxZvmN9nY/URquq1v2AoI/AAAAAAAAAbs/grj5uMhL6NA/s1024/Grass%252520Closeup.jpg",
"https://lh4.googleusercontent.com/-zAvf__52ONk/URqutT_IuxI/AAAAAAAAAbs/D_bcuc0thoU/s1024/Highway%2525201.jpg",
"https://lh4.googleusercontent.com/-vPeekyDjOE0/URquwzJ28qI/AAAAAAAAAbs/qxcyXULsZrg/s1024/Lake%252520Tahoe%252520Colors.jpg",
"https://lh3.googleusercontent.com/-897VXrJB6RE/URquxxxd-5I/AAAAAAAAAbs/j-Cz4T4YvIw/s1024/Leica%25252050mm%252520Summilux.jpg",
"https://lh3.googleusercontent.com/-D_5lNxnDN6g/URqu2Tk7HVI/AAAAAAAAAbs/p0ddca9W__Y/s1024/Lost%252520in%252520a%252520Field.jpg",
"https://lh4.googleusercontent.com/-Z4zGiC5nWdc/URqvBdEwivI/AAAAAAAAAbs/ZRZR1VJ84QA/s1024/Sin%252520Lights.jpg"
};
ViewPager pager;
CirclePageIndicator circleindicator;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.home, container, false);
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(getActivity()));
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.add_marker)
.resetViewBeforeLoading(true)
.cacheOnDisc(true)
.imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565)
.considerExifParams(true)
.displayer(new FadeInBitmapDisplayer(300))
.build();
pager = (ViewPager) rootView.findViewById(R.id.view_pagerhome);
pager.setAdapter(new ImagePagerAdapter(imageUrls));
circleindicator = (CirclePageIndicator) rootView.findViewById(R.id.indicatorhome);
circleindicator.setViewPager(pager);
pageSwitcher(); //This method will change the images automatically after a certain period of time
return rootView;
}
public static Timer getTimerValue()
{
return timer;
}
private void pageSwitcher() {
timer = new Timer(); // At this line a new Thread will be created
timer.scheduleAtFixedRate(new RemindTask(), 0, 3 * 1000);
// Delay in milliseconds
}
// this is an inner class...
class RemindTask extends TimerTask {
//Still to be executed, on manual change page
// Thought!! on pagechangelistener() set the pager.setCurrentItem to current position
//Find a way to determine the current position
//and when you find the current position update page and page1 items accordingly.
public void run() {
// As the TimerTask run on a seprate thread from UI thread we have
// to call runOnUiThread to do work on UI thread.
getActivity().runOnUiThread(new Runnable() {
public void run() {
if(page>8)
{
//This code will execute right to left
//Here page1 is decrement with the starting value of 8 equal to the number of pages
//On Reaching zero it should take the control to the else statement and execute
//left to right
//Managing manual view pager changes
y = pager.getCurrentItem();
y--;
page1 = y;
//managed
pager.setCurrentItem(page1--);
if(page1==-1)
{
page=-1;
flag=0;
}
}
else
{
//This code will execute from left to right.
//where page is the page number (total images - here 8)
//On reaching the end where page = 8, page 1 will set to 8 and then move
//right to left
//Managing manual view pager changes
if(flag==0)
{
int x = pager.getCurrentItem();
page = x;
flag = 1;
}
else
{
int x = pager.getCurrentItem();
x++;
page = x;
}
//managed
pager.setCurrentItem(page++);
if(page==8)
{
page1=8;
}
}
}
});
}
}
//This adapter is for the images on the top of home screen, the sliding images
private class ImagePagerAdapter extends PagerAdapter {
private String[] images;
ImagePagerAdapter(String[] images) {
this.images = images;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public int getCount() {
return images.length;
}
@Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = getLayoutInflater(getArguments()).inflate(R.layout.item_pager_image, view, false);
assert imageLayout != null;
ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image);
final ProgressBar spinner = (ProgressBar) imageLayout.findViewById(R.id.loading);
imageLoader.displayImage(images[position], imageView, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
spinner.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
spinner.setVisibility(View.GONE);
}
});
view.addView(imageLayout, 0);
return imageLayout;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
@Override
public Parcelable saveState() {
return null;
}
}
//End of adapter
}
这是我的logcat
如何解决这个问题? 我在MainActivity中所做的是调用timer变量并在活动结束前取消它。这就是我做到的。
@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
Timer timer = Home.getTimerValue();
timer.cancel();
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Press Again to Exit", Toast.LENGTH_SHORT).show();
}
如果我在MainActivity上,我再按两次,我就没有NPE。但是,如果我导航到另一个活动并返回到MainActivity,我会再次获得此异常。
答案 0 :(得分:2)
您希望计时器仅在片段处于活动状态时运行。关闭应用时,它可能仍在运行,getActivity()
此时可能会返回null
。在Timer
中创建并启动onStart()
,然后在片段onStop()
中取消它。这应该有用。