Reputation: 7964
I wanted to show a Button in my Listview in case I dont have data to fill in the list through custom Array adapter.Everything works fine in case I have data and my listview get filled with data items, but if i have no data item to show the listview should display the LinearLayout with id "@android:id/empty" but it never shows this up and my application got crash at this stage.In my FavoriteStudents.java class file I have an AsyncTask defined.In doInBackground method I check if favorite file exists in my phone internal memory to create adapter for listview, if not then stop AsyncTask and show list view with just a buttom.After it return from the doInBackground method it crashes and shows me this error:
10-16 16:06:37.568: E/WindowManager(274): Activity com.example.hellogridview.FavoriteStudets has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44bfea80 that was originally added here
10-16 16:06:37.568: E/WindowManager(274): android.view.WindowLeaked: Activity com.example.hellogridview.FavoriteStudents has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44bfea80 that was originally added here
10-16 16:06:37.568: E/WindowManager(274): at android.view.ViewRoot.<init>(ViewRoot.java:227)
10-16 16:06:37.568: E/WindowManager(274): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
10-16 16:06:37.568: E/WindowManager(274): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
10-16 16:06:37.568: E/WindowManager(274): at android.view.Window$LocalWindowManager.addView(Window.java:424)
10-16 16:06:37.568: E/WindowManager(274): at android.app.Dialog.show(Dialog.java:239)
10-16 16:06:37.568: E/WindowManager(274): at com.example.hellogridview.FavoriteStudents$readingFavFileTask.onPreExecute(FavoriteStudents.java:50)
10-16 16:06:37.568: E/WindowManager(274): at android.os.AsyncTask.execute(AsyncTask.java:391)
10-16 16:06:37.568: E/WindowManager(274): at com.example.hellogridview.FavoriteStudents.onCreate(FavoriteStudents.java:34)
10-16 16:06:37.568: E/WindowManager(274): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-16 16:06:37.568: E/WindowManager(274): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
10-16 16:06:37.568: E/WindowManager(274): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
10-16 16:06:37.568: E/WindowManager(274): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
10-16 16:06:37.568: E/WindowManager(274): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
10-16 16:06:37.568: E/WindowManager(274): at android.os.Handler.dispatchMessage(Handler.java:99)
10-16 16:06:37.568: E/WindowManager(274): at android.os.Looper.loop(Looper.java:123)
10-16 16:06:37.568: E/WindowManager(274): at android.app.ActivityThread.main(ActivityThread.java:4363)
10-16 16:06:37.568: E/WindowManager(274): at java.lang.reflect.Method.invokeNative(Native Method)
10-16 16:06:37.568: E/WindowManager(274): at java.lang.reflect.Method.invoke(Method.java:521)
10-16 16:06:37.568: E/WindowManager(274): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
10-16 16:06:37.568: E/WindowManager(274): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
10-16 16:06:37.568: E/WindowManager(274): at dalvik.system.NativeStart.main(Native Method)
My xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/studentsList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#b5b5b5"
android:dividerHeight="1dp"
android:listSelector="@drawable/student_list_selector" >
</ListView>
<!-- empty view -->
<LinearLayout
android:id="@android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="@+id/addStudents"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Students" >
</Button>
</LinearLayout>
</LinearLayout>
My Student adapter
public class StudentsAdapter extends ArrayAdapter<Students> {
private Context context;
ImageDownloaderNew imageDownloader;
ArrayList<Students> students;
Songs studentsTemp = null;
int targetWidth = 70;
int targetHeight = 110;
public StudentsAdapter (Context context, int textViewResourceId,
ArrayList<Students> students) {
super(context, textViewResourceId, songs);
// TODO Auto-generated constructor stub
this.context = context;
this.students= students;
imageDownloader = new ImageDownloaderNew();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return students.size();
}
@Override
public Students getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
static class ViewHolder {
protected TextView studentTitle;
protected RatingBar studentRating;
protected TextView studentViews;
protected ImageView studentImage;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
//My getView code goes here.I have not pasted here
return convertView;
}
}
Now FavoriteStudents.java class file
public class FavoriteStudents extends SherlockActivity {
ListView list;
StudentsAdapter adapter;
ArrayList<Students> studentsListArray = new ArrayList<Students>();
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.students_list);
new readingFavFileTask().execute(UtilityFuctions.FAV_STUDENTS_FILE_NAME);
}
private class readingFavFileTask extends AsyncTask<String, Void, String> {
ProgressDialog m_dialog = new ProgressDialog(FavoriteStudents.this);
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// initialize the dialog
m_dialog.setTitle("Loading...");
m_dialog.setMessage("Please wait while loading...");
m_dialog.setIndeterminate(true);
m_dialog.setCancelable(true);
m_dialog.show();
}
@Override
protected String doInBackground(String... params) {
if (!UtilityFuctions.isFileExists(getApplicationContext(),
params[0])) {
// favorite file does not exists
finish();
return "fileDoesNotExists";
}else{
StudentsListArray = UtilityFuctions.readFavJSONFile(
getApplicationContext(), params[0]);
if (isCancelled())
finish();
return null;}
}
@Override
protected void onPostExecute(String result) {
list = (ListView) findViewById(R.id.studentsList);
if (result.equals("fileDoesNotExists")) {
adapter = new StudentsAdapter(FavoriteStudents.this, 1,
studentsListArray);
list.setAdapter(adapter);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View myView = inflater.inflate(R.layout.empty_view, null);
list.setEmptyView(myView);
m_dialog.dismiss();
} else {
// Creating a StudentsAdapter and setting it on listview
adapter = new StudentsAdapter(FavoriteStudents.this, 1,
studentsListArray);
list.setAdapter(adapter);
m_dialog.dismiss();
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//onItemClick code goes here
}
});
}
}
}
}
EDIT: @Rolf Smith answer is correct.But The main problem is I am calling finish() in my doInBackground() method which is killing my activity and not showing me the emptyView.So i just remove finish() and everything working perfectly. Thanks EveryOne
Upvotes: 0
Views: 3101
Reputation: 8781
The empty view (using the android empty id) only works when you use a ListActivity or ListFragment, in this case you have to do the logic your self using the setEmptyView()
method.
and the crash you got is probably because the dialog you have shown is not dismissed when your activity closes. So for example in the onPause method call the dismiss method from the dialog you have shown.
Rolf
Edit see comments:
The empty view will be shown with View.GONE and View.VISIBLE this means that you don't need to add it your self etc.
Take a look at this code: And take a good look at the onCreate method.
import android.widget.ListView;
public class FavoriteStudents extends SherlockActivity {
ListView list;
StudentsAdapter adapter;
ArrayList<Students> studentsListArray = new ArrayList<Students>();
private ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.students_list);
list = (ListView) findViewById(R.id.studentsList);
View empty = findViewById(R.id.empty_view);
list.setEmptyView(empty);
new readingFavFileTask().execute(UtilityFuctions.FAV_STUDENTS_FILE_NAME);
}
private class readingFavFileTask extends AsyncTask<String, Void, String> {
ProgressDialog m_dialog = new ProgressDialog(FavoriteStudents.this);
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// initialize the dialog
m_dialog.setTitle("Loading...");
m_dialog.setMessage("Please wait while loading...");
m_dialog.setIndeterminate(true);
m_dialog.setCancelable(true);
m_dialog.show();
}
@Override
protected String doInBackground(String... params) {
if (!UtilityFuctions.isFileExists(getApplicationContext(),
params[0])) {
// favorite file does not exists
finish();
return "fileDoesNotExists";
}else{
StudentsListArray = UtilityFuctions.readFavJSONFile(
getApplicationContext(), params[0]);
if (isCancelled())
finish();
return null;}
}
@Override
protected void onPostExecute(String result) {
if (result.equals("fileDoesNotExists")) {
adapter = new StudentsAdapter(FavoriteStudents.this, 1, studentsListArray);
list.setAdapter(adapter);
m_dialog.dismiss();
} else {
// Creating a StudentsAdapter and setting it on listview
adapter = new StudentsAdapter(FavoriteStudents.this, 1,
studentsListArray);
list.setAdapter(adapter);
m_dialog.dismiss();
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//onItemClick code goes here
}
});
}
}
}
}
Upvotes: 6