In my app i have nothing but an asynctask that gets data from database into listview but if there is no data nothing shows and when i press the back button the app is not responding the problem is there is no even errors in my logs not even a single error.
When i press the back button it starts lagging and then it says app is not responding but f there is data in my database the application acts normally.
Any ideas?
private class SyncData extends AsyncTask<String, String, String> {
String msg;
#Override
protected void onPreExecute() //Starts the progress dailog
{
System.out.println("Start");
//lottieAnimationView.playAnimation();
customProgress.showProgress(supervisor_specialty.this, "Loading..."
, false);
}
#Override
protected String doInBackground(String... strings) // Connect to the database, write query and add items to array list
{
try {
Connection conn = connectionClass.CONN(); //Connection Object
if (conn == null) {
success = false;
msg = "Sorry something went wrong,Please check your internet connection";
} else {
// Change below query according to your own database.
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
if (rs != null) // if resultset not null, I add items to itemArraylist using class created
{
while (rs.next()) {
try {
Blob rsBlob = rs.getBlob("Store_Picture");
Boolean active = rs.getBoolean("Active");
itemArrayList.add(new ClassLista(rs.getString("StoreArabicName"),active,rsBlob));
//Picasso.with(agzakhana_mainAr.this).load(rs.getString("SpecialityIcon")).into(specialityicon);
} catch (Exception ex) {
ex.printStackTrace();
}
}
msg = "تم";
success = true;
} else {
msg = "No Data found!";
success = false;
}
}
} catch (Exception e) {
e.printStackTrace();
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
msg = writer.toString();
Log.d("Error", writer.toString());
success = false;
}
return msg;
}
#Override
protected void onPostExecute(String msg) // disimissing progress dialoge, showing error and setting up my listview
{
//progress2.hideProgress();
customProgress.hideProgress();
System.out.println("End");
if (msg != null) {
Toast.makeText(supervisor_specialty.this, msg + "", Toast.LENGTH_LONG).show();
}
if (!success) {
} else {
try {
myAppAdapter = new MyAppAdapter(itemArrayList, supervisor_specialty.this);
while (myAppAdapter.getCount() == 0) {
}
listView21.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView21.setAdapter(myAppAdapter);
} catch (Exception ex) {
}
}
}
}
public class MyAppAdapter extends BaseAdapter//has a class viewholder which holds
{
public class ViewHolder {
TextView StoreName;
ImageView active;
ImageView StoreIcon;
}
public List<ClassLista> parkingList;
public Context context;
ArrayList<ClassLista> arraylist;
private MyAppAdapter(List<ClassLista> apps, Context context) {
this.parkingList = apps;
this.context = context;
arraylist = new ArrayList<ClassLista>();
arraylist.addAll(parkingList);
}
#Override
public int getCount() {
return parkingList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) // inflating the layout and initializing widgets
{
View rowView = convertView;
MyAppAdapter.ViewHolder viewHolder = null;
if (rowView == null) {
LayoutInflater inflater = getLayoutInflater();
rowView = inflater.inflate(R.layout.listitems2, parent, false);
viewHolder = new MyAppAdapter.ViewHolder();
viewHolder.StoreName = rowView.findViewById(R.id.store_name);
viewHolder.active = rowView.findViewById(R.id.active);
viewHolder.StoreIcon = rowView.findViewById(R.id.store_pic);
rowView.setTag(viewHolder);
} else {
viewHolder = (MyAppAdapter.ViewHolder) convertView.getTag();
}
// here setting up names and images
if (parkingList.get(position).getName() != null){
viewHolder.StoreName.setText(parkingList.get(position).getName() + "");
}
if(parkingList.get(position).getActive()){
viewHolder.active.setImageResource(R.drawable.checkk);
}else {
viewHolder.active.setImageResource(R.drawable.timer);
}
Blob blob = parkingList.get(position).getStoreicon();
if (blob!= null){
byte[] decodedString = new byte[0];
try {
decodedString = Base64.decode(blob.getBytes(1,(int) blob.length()), Base64.NO_WRAP);
} catch (SQLException e) {
e.printStackTrace();
}
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
viewHolder.StoreIcon.setImageBitmap(decodedByte);
}else {
viewHolder.StoreIcon.setImageResource(R.drawable.agzakahana);
}
// Picasso.with(context).load(parkingList.get(position).getDiscountimage()).into(viewHolder.imagediscount);
listView21.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//What happens when you click on a place!
// Intent intent = new Intent(LoggedIn.this,MapsActivity.class);
// startActivity(intent);
}
});
//LayoutAnimationController lac = new LayoutAnimationController(AnimationUtils.loadAnimation(context, R.anim.thelistanim), 0.3f); //0.5f == time between appearance of listview items.
//listView21.setLayoutAnimation(lac);
//listView21.startLayoutAnimation();
return rowView;
}
}
When executing this code :
ResultSet rs = stmt.executeQuery(query);
if there are no data, this not mean that it should be null!
So when you check
if (rs != null)
while (rs.next())
So the while loop causes an infinite loop that leads to lags than crash with the app.
Related
i am trying to send Data (ID value) from one activity to other
but it wouldn't send correct data , i want it to send only ID Value of Clicked Item to next activity , here is my code
public class Order extends AppCompatActivity {
private ListView lvUsers;
private ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub);
dialog = new ProgressDialog(this);
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.setMessage("Loading, please wait.....");
lvUsers = (ListView) findViewById(R.id.lvUsers);
new JSONTask().execute("http://146.185.178.83/resttest/order");
}
public class JSONTask extends AsyncTask<String, String, List<OrderModel> > {
#Override
protected void onPreExecute(){
super.onPreExecute();
dialog.show();
}
#Override
protected List<OrderModel> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line ="";
while ((line=reader.readLine()) !=null){
buffer.append(line);
}
String finalJson = buffer.toString();
JSONArray parentArray = new JSONArray(finalJson);
List<OrderModel> orderModelList = new ArrayList<>();
Gson gson = new Gson();
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
OrderModel orderModel = gson.fromJson(finalObject.toString(), OrderModel.class);
orderModelList.add(orderModel);
}
return orderModelList;
}catch (MalformedURLException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if(connection !=null) {
connection.disconnect();
}
try {
if (reader !=null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(List<OrderModel> result) {
super.onPostExecute(result);
dialog.dismiss();
OrderAdapter adapter = new OrderAdapter(getApplicationContext(), R.layout.row_order, result);
lvUsers.setAdapter(adapter);
}
}
public class OrderAdapter extends ArrayAdapter {
public List<OrderModel> orderModelList;
private int resource;
private LayoutInflater inflater;
public OrderAdapter(Context context, int resource, List<OrderModel> objects) {
super(context, resource, objects);
orderModelList = objects;
this.resource = resource;
inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
holder = new ViewHolder();
convertView=inflater.inflate(resource, null);
holder.bOrderNo = (Button) convertView.findViewById(R.id.bOrderNo);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
final int orderId = orderModelList.get(position).getId();
holder.bOrderNo.setText("Order No: " + orderModelList.get(position).getOrderId());
holder.bOrderNo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Order.this, OrderSelected.class);
intent.putExtra("parameter_name", orderId);
startActivity(intent);
}
});
return convertView;
}
class ViewHolder{
private Button bOrderNo;
}
}
}
The holder gets executed in loop i guess is why it wouldn't send right Id.
How do i get it to send only Id of the clicked orderId
you can check this link to see how json Response looks like http://146.185.178.83/resttest/order
You have a silly mistake in your code . I have edited single line in your code . I think you are getting same "orderId" every time instead of actual "orderId". Check this one . I hope your problem will resolve .
final int index = position;
holder.bOrderNo.setText("Order No: " + orderModelList.get(position).getOrderId());
holder.bOrderNo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Order.this, OrderSelected.class);
intent.putExtra("parameter_name", orderModelList.get(index).getId());
startActivity(intent);
}
});
Please try
In place of
intent.putExtra("parameter_name", orderId);
Please put
intent.putExtra("parameter_name", orderModelList.get(position).getId());
I have an Activity called Myprofile and a baseAdapter called Myprofile_CustomView on my activity I get Json data which then I convert into a ArrayList with a hashmap and my question is how can I retrieve the values of the hashmap in the baseadapter ?
This is my activity Myprofile
public class Myprofile extends Activity {
String URI_URL;
Integer page;
ProgressBar pb;
ListView mm;
Myprofile_CustomView BA;
ArrayList<HashMap<String,String>> userslist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myprofile);
URI_URL = getResources().getString(R.string.PathUrl) + "/api/myprofile";
page=0;
// Listview for adapter
mm= (ListView)findViewById(R.id.myprofiles);
new Myprofile_Async().execute();
}
public class Myprofile_Async extends AsyncTask<String,String,String> {
HttpURLConnection conn;
URL url;
String result="";
DataOutputStream wr;
int id;
#Override
protected void onPreExecute() {
super.onPreExecute();
pb=(ProgressBar)findViewById(R.id.progressBar);
pb.setVisibility(View.VISIBLE);
id= getIntent().getExtras().getInt("id");
// page Int is used to keep count of scroll events
if(page==0)
{page=1;}
else {page=page+1;}
Toast.makeText(Myprofile.this,""+page,Toast.LENGTH_SHORT).show();
}
#Override
protected String doInBackground(String... params) {
// Gets data from api
BufferedReader reader=null;
String cert="id="+id+"&page="+page;
try{
url = new URL(URI_URL);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(cert);
wr.flush();
wr.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
sBuilder.append(line + "\n");
}
result = sBuilder.toString();
reader.close();
conn.disconnect();
return result;
}
catch (Exception e)
{
e.printStackTrace();
}
System.err.println("cassies" + result);
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
HashMap<String,String> map= new HashMap<>();
JSONObject jsonn= new JSONObject(result);
JSONArray jArray = jsonn.getJSONArray("myprofile");
JSONObject jobject=null;
JSONArray sss= new JSONArray();
for(int i=0; i < jArray.length(); i++) {
jobject= jArray.getJSONObject(i);
map.put("fullname",jobject.getString("fullname"));
sss.put(jobject);
}
jsonn.put("myprofile", sss);
// Add values to arrayList
userslist.add(map);
// Send information to BaseAdapter
BA= new Myprofile_CustomView(userslist,Myprofile.this);
mm.setAdapter(BA);
} catch (Exception e) {
System.err.println("mpee: " + e.toString());
}
pb.setVisibility(View.INVISIBLE);
}
}
}
this part above I have no issues with my problem is in the BaseAdapter with the ArrayList userList I don't know how to get HashMap keys from it. I am naming the keys because I have other fields that I will eventually do
public class Myprofile_CustomView extends BaseAdapter {
JSONObject names;
Context ctx;
LayoutInflater myiflater;
ArrayList<HashMap<String,String>> usersList;
// Have data come in and do a toast to see changes
public Myprofile_CustomView(ArrayList<HashMap<String,String>> arr, Context c) {
notifyDataSetChanged();
ctx = c;
usersList= arr;
myiflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
try {
JSONArray jaLocalstreams = names.getJSONArray("myprofile");
return jaLocalstreams.length();
} catch (Exception e) {
Toast.makeText(ctx, "Error: Please try again", Toast.LENGTH_LONG).show();
return names.length();
}
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
MyViewHolder holder=null;
try {
if(row==null) {
LayoutInflater li = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(R.layout.zmyprofile,parent,false);
holder=new MyViewHolder(row);
row.setTag(holder);
}
else
{
holder=(MyViewHolder)row.getTag();
}
// How can I get HashMap value for fullname here so I can set it to to Text
String fullname= usersList
holder.fullname.setText(fullname);
return row;
} catch (Exception e) {
e.printStackTrace();
}
return row;
}
class MyViewHolder{
TextView fullname;
MyViewHolder(View v)
{
fullname= (TextView)v.findViewById(R.id.fullname);
}
}
}
getCount should return the size of your dataset. In your case usersList
public int getCount() {
return usersList == null ? 0 : userLists.size();
}
int getView you want to retrieve the item at position:
HashMap<String, String> item = usersList.get(i);
String fullname = item.get("fullname");
the value of position changes with the scrolling,
I try to parse some xml files (RSS) and to create a custom ListView to display images, title and date. The only problem is that when I call RSS downloader class to download and parse xml file and create an adapter from it it give's me NullPointer Exception. I guess that it does not prove to parse xml file. Here is my code. Any help would be appreciated.
Activity fragment:
public class PublicaNewsActivity extends Fragment implements InterfaceFunc {
public static ArrayList<PostData> listData;
Context mContext;
InterfaceFunc mInterface;
ListView mListView;
static PostItemAdapter itemAdapter;
public enum RSSXMLTag {
TITLE, DATE, LINK, CONTENT, GUID, IGNORETAG;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.publica_news, container, false);
mContext = getActivity();
mInterface = this;
ListView listView = (ListView) view.findViewById(R.id.postListView);
new RssDataController().execute("http://www.jurnaltv.md/rss.xml");
itemAdapter = new PostItemAdapter(mContext,
R.layout.publica_item, listData);
listView.setAdapter(itemAdapter);
return view;
}
Here is the PostItemAdapter:
public class PostItemAdapter extends ArrayAdapter<PostData> {
private Activity myContext;
private ArrayList<PostData> datas;
static class ViewHolder {
TextView postTitleView;
TextView postDateView;
ImageView postThumbView;
}
public PostItemAdapter(Context context, int textViewResourceId,
ArrayList<PostData> listData) {
super(context, textViewResourceId, listData);
// TODO Auto-generated constructor stub
myContext = (Activity) context;
datas = listData;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.publica_item, null);
viewHolder = new ViewHolder();
viewHolder.postThumbView = (ImageView) convertView
.findViewById(R.id.postThumb);
viewHolder.postTitleView = (TextView) convertView
.findViewById(R.id.postTitleLabel);
viewHolder.postDateView = (TextView) convertView
.findViewById(R.id.postDateLabel);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (datas.get(position).postThumbUrl == null) {
viewHolder.postThumbView
.setImageResource(R.drawable.ic_launcher);
}
viewHolder.postTitleView.setText(datas.get(position).postTitle);
viewHolder.postDateView.setText(datas.get(position).postDate);
return convertView;
}
}
and the RSSDownloader:
class RssDataController extends
AsyncTask<String, Integer, ArrayList<PostData>> {
private RSSXMLTag currentTag;
#Override
protected ArrayList<PostData> doInBackground(String... params) {
// TODO Auto-generated method stub
String urlStr = params[0];
InputStream is = null;
ArrayList<PostData> postDataList = new ArrayList<PostData>();
try {
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setReadTimeout(10 * 1000);
connection.setConnectTimeout(10 * 1000);
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.connect();
int response = connection.getResponseCode();
Log.d("debug", "The response is: " + response);
is = connection.getInputStream();
// parse xml after getting the data
XmlPullParserFactory factory = XmlPullParserFactory
.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(is, null);
int eventType = xpp.getEventType();
PostData pdData = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(
"EEE, DD MMM yyyy HH:mm:ss");
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
} else if (eventType == XmlPullParser.START_TAG) {
if (xpp.getName().equals("item")) {
pdData = new PostData();
currentTag = RSSXMLTag.IGNORETAG;
} else if (xpp.getName().equals("title")) {
currentTag = RSSXMLTag.TITLE;
} else if (xpp.getName().equals("link")) {
currentTag = RSSXMLTag.LINK;
} else if (xpp.getName().equals("pubDate")) {
currentTag = RSSXMLTag.DATE;
}
} else if (eventType == XmlPullParser.END_TAG) {
if (xpp.getName().equals("item")) {
// format the data here, otherwise format data in
// Adapter
Date postDate = dateFormat.parse(pdData.postDate);
pdData.postDate = dateFormat.format(postDate);
postDataList.add(pdData);
} else {
currentTag = RSSXMLTag.IGNORETAG;
}
} else if (eventType == XmlPullParser.TEXT) {
String content = xpp.getText();
content = content.trim();
Log.d("debug", content);
if (pdData != null) {
switch (currentTag) {
case TITLE:
if (content.length() != 0) {
if (pdData.postTitle != null) {
pdData.postTitle += content;
} else {
pdData.postTitle = content;
}
}
break;
case LINK:
if (content.length() != 0) {
if (pdData.postLink != null) {
pdData.postLink += content;
} else {
pdData.postLink = content;
}
}
break;
case DATE:
if (content.length() != 0) {
if (pdData.postDate != null) {
pdData.postDate += content;
} else {
pdData.postDate = content;
}
}
break;
default:
break;
}
}
}
eventType = xpp.next();
}
Log.v("tst", String.valueOf((postDataList.size())));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return postDataList;
}
#Override
public void onPostExecute(ArrayList<PostData> result) {
// TODO Auto-generated method stub
for (int i = 0; i < result.size(); i++) {
PublicaNewsActivity.listData.add(result.get(i));
}
PublicaNewsActivity.itemAdapter.notifyDataSetChanged();
}
}
This classes are originally created in this tutorial:
http://jmsliu.com/1390/rss-reader-app-android-tutorial-1-listview-and-arrayadapter.html
ArrayList<PostData> listData is not initiated anywhere which gives null pointer exception.
Initialize it like:
listdata = new ArrayList listData();
before executing AsyncTask
Im trying to code an android RSS reader that will (for now) parse the xml from this MangaPanda List. I'm using this Android XML example for basic structure (and because it uses XMLPullParser) as well as this example because of its clear explanation of its EfficientAdapter, AsyncTask, and ListView usage.
So far I think I've "merged" the two pretty well but I cant quite figure out how to properly execute the parsing process.
My question is: How would I properly implement the LoadXmlFromNetwork() so that it would return the proper format for my adapter?
MainActivity:
//Implementation of AsyncTask used to download XML feed from stackoverflow.com.
private class loadingTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
try {
return loadXmlFromNetwork(urls[0]);
} catch (IOException e) {
return getResources().getString(R.string.hello_world);
} catch (XmlPullParserException e) {
return getResources().getString(R.string.menu_settings);
}
}
#Override
protected void onPostExecute(String result) {
setContentView(R.layout.activity_main);
// Displays the HTML string in the UI via a WebView
listview1.setAdapter(new EfficientAdapter(MainActivity.this, Manga));
ShowProgress.dismiss();
}
}
public Manga loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {
InputStream stream = null;
// Instantiate the parser
MainParser MainParser = new MainParser();
List<Manga> mangas = null;
String mangaAlpha = null;
String mangaName = null;
boolean mangaComplete = false;
try {
stream = downloadUrl(urlString);
mangas = MainParser.parse(stream);
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (stream != null) {
stream.close();
}
}
// StackOverflowXmlParser returns a List (called "entries") of Entry objects.
// Each Entry object represents a single post in the XML feed.
// This section processes the entries list to combine each entry with HTML markup.
// Each entry is displayed in the UI as a link that optionally includes
// a text summary.
return mangas;
}
// Given a string representation of a URL, sets up a connection and gets
// an input stream.
private InputStream downloadUrl(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
return stream;
}
}
MainParser:
public class MainParser {
// We don't use namespaces
private static final String ns = null;
public List<Manga> parse(InputStream in) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in, null);
parser.nextTag();
return readFeed(parser);
} finally {
in.close();
}
}
private List<Manga> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Manga> mangas = new ArrayList<Manga>();
parser.require(XmlPullParser.START_TAG, ns, "feed");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Starts by looking for the entry tag
if (name.equals("li")) {
mangas.add(readTag(parser));
} else {
skip(parser);
}
}
return mangas;
}
private Manga readTag(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "li");
String mangaAlpha =null;
String mangaName = null;
String mangaLink = null;
boolean mangaComplete = false;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("a")) {
mangaAlpha = parser.getAttributeValue(null, "name");
} else if (name.equals("a")) {
mangaName = parser.getText();
} else if (name.equals("a")) {
mangaLink = parser.getAttributeValue(null, "href");
} else if (name.equals("span")) {
mangaComplete = true;
} else {
skip(parser);
}
}
return new Manga(mangaAlpha, mangaName, mangaLink, mangaComplete);
}
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
}
My EfficientAdapter:
public class EfficientAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<Manga> mangadata;
private static LayoutInflater inflater = null;
//public ImageLoader imageLoader;
ViewHolder holder;
EfficientAdapter(Activity a, ArrayList<Manga> d) {
activity = a;
mangadata = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//imageLoader = new ImageLoader(activity.getApplicationContext());
}
#Override
public int getCount() {
return mangadata.toArray().length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public static class ViewHolder {
public TextView label;
public TextView addr;
//public ImageView image;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.textholder, null);
holder = new ViewHolder();
holder.label = (TextView) vi.findViewById(R.id.textView1);
holder.addr = (TextView) vi.findViewById(R.id.textView2);
//holder.image = (ImageView) vi.findViewById(R.id.icon);
vi.setTag(holder);
} else
holder = (ViewHolder) vi.getTag();
holder.label.setText(mangadata.get(position).getMangaAlpha());
holder.addr.setText(mangadata.get(position).getMangaName());
//imageLoader.DisplayImage((data.get(position).getThumbnail()), activity,
// holder.image, 72, 72);
return vi;
}
}
On a side note: I didn't know how much of my code would be necessary to properly explain my problem so please feel free to edit out unnecessary parts.
Change your asynctask like that:
private class loadingTask extends AsyncTask<String, Void, List<Manga>> {
#Override
protected String doInBackground(String... urls) {
try {
return loadXmlFromNetwork(urls[0]);
} catch (IOException e) {
return null;
} catch (XmlPullParserException e) {
return null;
}
}
#Override
protected void onPostExecute(List<Manga> result) {
setContentView(R.layout.activity_main);
// Displays the HTML string in the UI via a WebView
listview1.setAdapter(new EfficientAdapter(MainActivity.this, result));
ShowProgress.dismiss();
}
}
public List<Manga> loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {
....
I have a ListAdapter that contains a bunch of images that are being downloaded from the internet. When I scroll up and down there seems to be a performance hit and things get jerky. How can I resolve this?
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.message_row, null);
}
STMessage aMessage = messages.get(position);
if (aMessage != null) {
TextView usernameTextView = (TextView) v.findViewById(R.id.usernameTextView);
TextView bodyTextView = (TextView) v.findViewById(R.id.bodyTextView);
TextView dateTextView = (TextView) v.findViewById(R.id.dateTextView);
ImageView avatarImageView = (ImageView)v.findViewById(R.id.avatarImageView);
if (usernameTextView != null) {
usernameTextView.setText(Html.fromHtml(aMessage.getUser_login()));
}
if (bodyTextView != null) {
bodyTextView.setText(aMessage.getBody());
//linkify urls
Linkify.addLinks(bodyTextView, Linkify.WEB_URLS);
//linkify symbols
Pattern symbolMatcher = Pattern.compile("/(?:^|\\s|[\\.(\\+\\-\\,])(?:\\$?)\\$((?:[0-9]+(?=[a-z])|(?![0-9\\.\\:\\_\\-]))(?:[a-z0-9]|[\\_\\.\\-\\:](?![\\.\\_\\.\\-\\:]))*[a-z0-9]+)/i");
String symbolURL = "content://com.stocktwits.activity/symbol/";
Linkify.addLinks(bodyTextView, symbolMatcher, symbolURL);
}
if (dateTextView != null) {
dateTextView.setText(aMessage.getUpdated_at());
}
if (avatarImageView != null) {
imageDownloader.download(aMessage.getAvatar_url(), avatarImageView);
}
}
return v;
}
Use Lazy Loading of Images - Lazy load of images in ListView
Maybe by using a Threads pool (queue) and placing a temporal image in the meantime?
Here is a nice way to go about it.
At least I think its nice. I did it :)
here is the class I used to load the ImageView in the background.
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
private ImageView destination;
private String cachedFile;
private Date startTime;
private DownloadCompletedListener completedListener;
public DownloadImageTask(ImageView destination, String cachedFile, DownloadCompletedListener completedListener)
{
this.destination = destination;
this.cachedFile = cachedFile;
this.startTime = new Date();
this.completedListener = completedListener;
}
protected Bitmap doInBackground(String... urls)
{
Bitmap result = getBitmapFromURL(urls[0]);
if (result != null)
{
try {
FileOutputStream out = new FileOutputStream(HSAppUtil.getFilePath(getFilenameFromUrl(urls[0])));
result.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
result = Bitmap.createBitmap(1,1,Config.ARGB_8888);
}
return result;
}
public String getHost() {
return "http://MyMainHost";
}
public Bitmap getBitmapFromURL(String fileUrl) {
String newFileUrl = null;
if (!fileUrl.contains("://"))
{
newFileUrl = getHost() + fileUrl;
}
else
{
newFileUrl = fileUrl;
}
URL myFileUrl = null;
try {
myFileUrl = new URL(newFileUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
length++;
return BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Bitmap result)
{
synchronized (destination)
{
Date lastUpdated = (Date)destination.getTag();
if (lastUpdated == null || lastUpdated.before(startTime))
{
boolean handled = false;
if (completedListener != null)
{
handled = completedListener.handleDownloadCompleted(destination, result);
}
if (!handled && destination != null)
{
destination.setTag(startTime);
destination.setImageBitmap(result);
}
}
result = null;
}
}
public interface DownloadCompletedListener {
boolean handleDownloadCompleted(ImageView i, Bitmap b);
}
}
then when you want to use it, You would call it like this.
new DownloadImageTask(imView, fileUrl, completedListener).execute(fileUrl);
and send the imView to the UI. it will load the image in when it downloads it.
Please give me your honest feedback.