Possible incorrect referencing - android

I have been trying to fix this bug for 3-4 hours, and i don't really know what else to try...
Here is how the program should work:
When an alarm is set, it goes off and asks JSON parser class to fetch some numbers.
JSONParser class does exactly that, and when i put results into object and try to update the database, nothing is happening.
JSONParser returns the string with numbers, which indicates that it does actually do what it is supposed to, and also database works properly in different methods.
It is because of this, that i suspect that my reference to the object isn't good, and that is the reason that this isn't working, but i cannot see any mistakes... Here is the code:
Alarm class ( where the Ticket object is drawn from the database) :
public void onReceive(Context context, Intent intent) {
/*acquire power service manager*/
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"TAG");
wl.acquire();
boolean boot = intent.getBooleanExtra("boot", false);
if(boot==true){
findTicketAndSetAlarm(context);
}
else{
Bundle b = intent.getBundleExtra("Bundle");
UUID id = UUID.fromString(b.getString("Key"));
DBHelper db = new DBHelper(context.getApplicationContext());
currentTicket = db.getTicket(id);
if(Global.isNetworkAvailable(context)){
JSONParser parser = new JSONParser(context, currentTicket,true,null);
parser.execute("http://www.millipiyango.gov.tr/sonuclar/cekilisler/sayisal/20150228.json");
}
else{
sendNotification(context,intent);
}
}
}
And here is the JSONParser class onPostExecute method:
#Override
protected void onPostExecute(String result) {
if(result == null){
if(mNotification)
Alarm.notifyUser(mContext, mTicket);
else
mActivity.notify(false);
}
else{
try {
int numbers[] = new int[6];
numbers = getJSON(numbers,result); //GETS the numbers from REST service
saveResultsToTicket(numbers);
String sResult = Global.getStringFromArray(numbers); //STRING WITH WORKING NUMBERS
if(mNotification)
Alarm.notifyUser(mContext, mTicket,sResult,mContext.getResources().getString(R.string.these_numbers_were_picked_));
else
mActivity.notify(true);
} catch (JSONException e) {
if(mNotification)
Alarm.notifyUser(mContext, mTicket);
else
mActivity.notify(false);
e.printStackTrace();
}
}
super.onPostExecute(result);
}
private void saveResultsToTicket(int[] numbers) {
mTicket.setResultNumbers(numbers);
ArrayList<Row> rows = new ArrayList<Row>();
rows = mTicket.getRows();
Iterator<Row> i = rows.iterator();
while(i.hasNext()){
Row r = i.next();
if((r.checkNumbers(numbers)).length >= 3){
mTicket.setWon(Global.WIN);
return;
}
}
mTicket.setWon(Global.LOSE);
commit();
}
private void commit() {
DBOperator dbOp = new DBOperator(mContext.getApplicationContext(), Global.UPDATE);
dbOp.execute(mTicket);
}
Thanks!

So, apparently, the method name commit is used in java, and Eclipse doesn't show any warning or error if by some chance you name your method exactly the same.
So method name was the problem i was facing...

Related

Activity get stuck in Looper.java

One of my app's activities has ran into an issue; the problem seems to be an asynk-task, which get information from the server and generate a list of n elements in a view using that data, this, get the activity stuck in the white load screen instead of rendering the view.
No crashes or errors.
I can press back button and return to previous activity(Not freeze).
Android monitor show no cpu usage.
Here is the code.Is called at the end of onCreate()
new AsyncTask() {
#Override
protected void onPreExecute() {
mProgressDialog.show();
}
#Override
protected Object doInBackground(Object[] params) {
Document dom = null;
Detalle detalle= getIntent().getParcelableExtra("pedido");
try {
dom=DetalleToXml.getDom(detalle);
} catch (Exception e) {
e.printStackTrace();
}
return dom;
}
protected void onPostExecute(Object o) {
Document dom = (Document)o;
mProgressDialog.dismiss();
TableLayout t = (TableLayout) contentView.findViewById(R.id.grid_layout_pedido);
t.removeAllViewsInLayout();
final NodeList rows = dom.getElementsByTagName("row");
if(rows.getLength() == 0) {
Toast.makeText(DetallesPedido.this, "La búsqueda no ha tenido resultados.", Toast.LENGTH_SHORT).show();
}else{
for(int i = 0; i < rows.getLength(); i++){
Element e = (Element)rows.item(i);
LayoutInflater inflater = LayoutInflater.from(getBaseContext());
String rowid = UtilesDom.getValue(e, "rowid");
String articulo = UtilesDom.getValue(e, "articulo");
String precio_venta = UtilesDom.getValue(e, "precio_venta");
String cantidad = UtilesDom.getValue(e, "cantidad");
String descripcion = UtilesDom.getValue(e, "descripcion");
LinearLayout bigRow=(LinearLayout)inflater.inflate(R.layout.pedido_detalle,null);
TextView tv=(TextView) bigRow.findViewById(R.id.detalle_row_textView1);
tv.setText(articulo);
tv=(TextView) bigRow.findViewById(R.id.detalle_row_textView3);
tv.setText(precio_venta);
tv=(TextView) bigRow.findViewById(R.id.detalle_row_textView2);
tv.setText(cantidad);
tv=(TextView) bigRow.findViewById(R.id.detalle_row_textView4);
tv.setText(descripcion);
try {
bigRow.setId(Integer.parseInt(rowid));
} catch (Exception e2) {
e2.printStackTrace();
}
bigRow.setTag(articulo);
bigRow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String codigo = (String) v.getTag();
final Context context = v.getContext();
final int rowid = v.getId();
Intent intent = new Intent(context, DetalleFicha.class);
Bundle b = new Bundle(3);
b.putInt("rowid", rowid);
b.putInt("operation",UtilesABM.UPDATE);
b.putString("caller","DetallesPedido");
intent.putExtras(b);
intent.putExtra("pedido",getIntent().getParcelableExtra("pedido"));
loaded = false;
startActivity(intent);
}
}
);
//UtilesViews.setDefaultPadding(tv);
t.addView(bigRow);
}
}
super.onPostExecute(o);
}
}.execute(query);
By debugging i can reach the Loop.java class right after execute() and there is where gets stuck.
Any ideas of how to fix it or the cause of the problem?
You are performing very performance costly call
LinearLayout bigRow=(LinearLayout)inflater.inflate(R.layout.pedido_detalle,null);
which can take too much time, and since you are doing it in onPostExecute call, which is being called on main thread, so main thread will gets blocked if number of rows are huge and app becomes unresponsive
Solution to this is, you can use recycler view

Why is it not possible to loop a call execute to get multiple responses inside my IntentService via Retrofit?

Why is it not possible to loop a call execute to get multiple responses inside my IntentService via Retrofit?
Please see my code:
public class UpdateAgendaService extends IntentService {
public static final int STATUS_RUNNING = 0;
public static final int STATUS_FINISHED = 1;
public static final int STATUS_ERROR = 2;
private Agenda agenda;
public UpdateAgendaService() {
super(UpdateAgendaService.class.getName());
}
#Override
protected void onHandleIntent(Intent intent) {
final ResultReceiver receiver = intent.getParcelableExtra("receiver");
String[] dateWeek = intent.getStringArrayExtra("dateWeek");
if (dateWeek != null) {
receiver.send(STATUS_RUNNING, Bundle.EMPTY);
Bundle bundle = new Bundle();
try {
//Why is this not possible?
List<Agenda> agendaList = getAgendaList(dateWeek);
receiver.send(STATUS_FINISHED, bundle);
}
} catch (Exception e) {
/* Sending error message back to activity */
bundle.putString(Intent.EXTRA_TEXT, e.toString());
receiver.send(STATUS_ERROR, bundle);
}
}
Log.d(Utilities.TAG, "Service Stopping!");
this.stopSelf();
}
private List<Agenda> getAgendaList(String[] upcomingWeekdates){
List<Agenda> agendaList = null;
for (int i = 0; i < upcomingWeekdates.length; i++) {
String weekDay = upcomingWeekdates[i];
agendaList.add(getAgenda(weekDay));
}
return agendaList;
}
private Agenda getAgenda(String date) {
Agenda agenda = null;
ApiService apiService = new QardioApi().getApiService();
Call<Agenda> call = apiService.getAgenda(date);
try {
agenda = call.execute().body();
} catch (IOException e) {
e.printStackTrace();
}
return agenda;
}
}
So the situation is that I have an API which has a url: http//:myapi.com/[date] which when called via retrofit gives me a JSON response of the Agenda(Events) for that specific day. What I want to do is to show the agenda(events) for the upcoming week, that is why I did it via loop given a String array of dates for the upcoming week. Imagine kind of like the Eventbrite app.
What I am doing wrong? I read somewhere that I should do this via JobQueue/Eventbus, should I be doing that? But I am a bit hesitant because I don't want to be using any more third party libraries. However, if that is the last case scenario I will probably just go with that then.
Nevermind guys. That was because of a very stupid mistake i made.
I just changed:
List<Agenda> agendaList = null;
to
List<Agenda> agendaList = new ArrayList<>();

AsyncTask not running onPostExexute in Activity launched from Notification

I am writing an Android App that checks for new messages in the background using AlarmManager and WakefulBroadcastReceiver. The Receiver starts an IntentService and that uses an AsyncTask for the network request (HTTPClient).
After a reboot, the alarm is re-enabled using a BroadcastReceiver listening for android.intent.action.BOOT_COMPLETED.
The problem occures when the onCreate method of my main Activity loads the full message contents using an AsyncTask, but only under certain circumstances:
java.lang.RuntimeException: Handler (android.os.AsyncTask$InternalHandler) {4139f618} sending message to a Handler on a dead thread
The doInBackground is executed and returns a String with valid content, but instead of executing onPostExecute, the excaption rises.
There are several scenarios:
I start the app from the launcher -> WORKS.
The App has been started like (1), sent to background and then a message arrives. The Notification is tapped, the Activity starts -> WORKS.
The App has been started like (1), send to background and the device was rebooted. A message arrives, the notification is tapped, the Activity starts -> EXCEPTION.
Question: How can I fix that, without burning in the developer hell for doing network requests on the UI thread?
Searching for a solution, I found onPostExecute not being called in AsyncTask (Handler runtime exception), but neither the solution from "sdw" nor from "Jonathan Perlow" changes a thing.
ServerQuery:
public abstract class ServerQuery extends AsyncTask<Void, Void, String> {
protected Context context;
String user = "ERR";
String pin = "ERR";
String cmd = "ERR";
ServerQuery(Context context, String _user, String _pin, String _cmd) {
this.context = context;
user = _user;
pin = _pin;
cmd = _cmd;
}
private ServerQuery() {
}
#Override
protected String doInBackground(Void... params) {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair(context.getString(R.string.post_client), context.getString(R.string.post_client_app)));
nameValuePairs.add(new BasicNameValuePair(context.getString(R.string.post_user), user));
nameValuePairs.add(new BasicNameValuePair(context.getString(R.string.post_pin), pin));
nameValuePairs.add(new BasicNameValuePair(context.getString(R.string.post_cmd), cmd));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://[my server hostname]/index.php");
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
} catch (UnsupportedEncodingException e) {
return "ERR";
}
HttpResponse httpResponse = null;
try{
httpResponse = httpClient.execute(httpPost);
}catch (Exception e) {
return "ERR";
}
HttpEntity httpEntity = httpResponse.getEntity();
InputStream inputStream = null;
try {
inputStream = httpEntity.getContent();
} catch (IOException e) {
return "ERR";
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String s = null;
try {
while ((s = bufferedReader.readLine()) != null) {
stringBuilder.append(s);
}
} catch (IOException e) {
return "ERR";
}
try {
inputStream.close();
} catch (IOException e) {
return "ERR";
}
return stringBuilder.toString();
}
}
lastID:
public class lastID extends ServerQuery {
Integer lastid, savedid;
lastID(Context context, String _user, String _pin, String _cmd) {
super(context, _user, _pin, _cmd);
lastid = -1;
}
#Override
protected void onPostExecute(final String success) {
if(success.equals("ERR") || success.length() < 1) {
Toast.makeText(context, context.getString(R.string.server_no_connection), Toast.LENGTH_LONG).show();
} else {
String content[] = success.split("(;)");
if(content.length == 2) {
lastid = Integer.parseInt(content[0]);
SharedPreferences sharedPreferences = context.getSharedPreferences(context.getString(R.string.settings_filename), 0);
SharedPreferences.Editor editor = sharedPreferences.edit();
savedid = sharedPreferences.getInt(context.getString(R.string.post_lastid), -1);
if (lastid > savedid) { // NEUES ANGEBOT!
editor.putInt(context.getString(R.string.post_lastid), lastid);
editor.commit();
// Benachrichtung
NotificationCompat.Builder notific = new NotificationCompat.Builder(context);
notific.setContentTitle(context.getString(R.string.notify_title));
notific.setContentText(content[1]);
notific.setSmallIcon(R.drawable.ic_notify);
notific.setAutoCancel(false);
notific.setPriority(NotificationCompat.PRIORITY_HIGH);
notific.setTicker(content[1]);
notific.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS);
Intent resultIntent = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_CANCEL_CURRENT);
notific.setContentIntent(resultPendingIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(lastid, notific.build());
}
}
}
}
}
MainActivity onCreate:
[ loading shared preferences, setting onclicklisteners ]
angebot = new Angebot(this, getApplicationContext(), user, pin, getString(R.string.post_cmd_viewAngebot));
angebot.execute((Void) null);
Angebot is like lastID, but it uses the String to fill the TextViews.
EDIT 1:
Angebot:
public class Angebot extends ServerQuery {
protected Activity activity;
protected TextView datumView;
// more TextView s
protected Button hungerButton;
Angebot(Activity activity, Context context, String _user, String _pin, String _cmd) {
super(context, _user, _pin, _cmd);
this.activity = activity;
datumView = (TextView) this.activity.findViewById(R.id.datum);
// finding all other TextView s
}
#Override
protected void onPreExecute() {
showProgress(true);
}
#Override
protected void onPostExecute(final String success) {
Log.v(C.TAG_ALARMESSEN, "Angebot.onPostExecute");
showProgress(false);
if(success.equals("ERR") || success.length() < 1) {
Toast.makeText(activity.getApplicationContext(), context.getString(R.string.server_no_connection), Toast.LENGTH_LONG).show();
} else {
String content[] = success.split("(;)");
// put each content string in a TextView
} else {
Toast.makeText(context, context.getString(R.string.err02s), Toast.LENGTH_LONG).show(); // nicht angemeldet
}
}
}
#Override
protected void onCancelled() {
showProgress(false);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public void showProgress(final boolean show) {
final View progressView = activity.findViewById(R.id.login_progress);
progressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
}
EDIT 2: stack trace:
java.lang.RuntimeException: Handler (android.os.AsyncTask$InternalHandler) {4139f618} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
at android.os.Handler.sendMessageAtTime(Handler.java:473)
at android.os.Handler.sendMessageDelayed(Handler.java:446)
at android.os.Handler.sendMessage(Handler.java:383)
at android.os.Message.sendToTarget(Message.java:363)
at android.os.AsyncTask.postResult(AsyncTask.java:300)
at android.os.AsyncTask.access$400(AsyncTask.java:156)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
I would assume that the workarounds for the AsyncTask bug mentioned here: onPostExecute not being called in AsyncTask (Handler runtime exception) would work in this case too but according to the OP they don't.
Instead of fixing the issue I would suggest to use an AsyncTaskLoader instead. There's plenty of articles about the difference (mainly the advantages) of AsyncTaskLoader compared to AsyncTask. Here are just two (good) examples):
http://www.javacodegeeks.com/2013/01/android-loaders-versus-asynctask.html and http://www.androiddesignpatterns.com/2012/07/loaders-and-loadermanager-background.html
The main advantages of an AsyncTaskLoader is that they are synced with the life cycle of the Activity or Fragment that started it and that they can deal with configuration changes gracefully (unlike AsyncTasks).
Here's how you'd implement it. First you need the AsyncLoaderClass:
class ServerQuery extends AsyncTaskLoader<String> {
String mResult;
public ServerQuery(Context context) {
super(context);
}
#Override
protected void onStartLoading() {
if (mResult == null) {
forceLoad(); // no data yet -> force load it
}
else {
deliverResult(mResult); // already got the data -> deliver it
}
}
#Override
public String loadInBackground() {
// load your data...
return mResult; // return the loaded data
}
#Override
public void cancelLoadInBackground() {
// do whatever it takes to stop loading
}
}
Replace the "// load your data..." part with whatever you have in your doInBackground method. That's all there is to the actual AsyncTaskLoader. As you can see there's no equivalent to onPostExecute and that's the beauty of the AsyncTaskLoader, it's there to load data, nothing else. All the issues that occurred because AsyncTask tried to update the ui on the onPostExecute are gone.
The logic in onPostExecute now resides completely in the Activity/Fragment that starts the loader. Here's how you do it:
LoaderManager loaderMgr = getLoaderManager();
loaderMgr.initLoader(0, null, this);
this stands for LoaderManager.LoaderCallbacks meaning you have to implement that interface in your fragment/activity like so:
#Override
public Loader<String> onCreateLoader(int id, Bundle args) {
return new ServerQuery(this);
}
#Override public void onLoaderReset(Loader<String> loader) {}
#Override
public void onLoadFinished(Loader<String> loader, String data) {
// here goes your code to update the ui (previously onPostExecute);
}
onCreateLoader simply creates your loader (ServerQuery in this case) which will be managed by the LoaderManager henceforth. onLoadFinished will be called when the data is delivered to your fragment/activity allowing you to update the ui. You can check out one of my other answers to get some more information about Loaders that might help you understand how they work: https://stackoverflow.com/a/20916507/534471. Especially the part about configuration changes might be helpful.

Android activity recreate itself

My app normally works just fine, until I face a strange problem on specific device. There are 2 activities in App. After I start ActivityB inside of ActivityA, ActivityA starts with no issue. However, after I go back to the ActivityA with pushing back hardware button or calling finish(); inside of closeButton in ActivityB, ActivityA reloads itself. It triggers onCreate() again and reloads all its contents. And I'm not changing orientation of phone. This strange behavior only appears in 15 phones over 1.000 download of app.
This problem only occurs on Galaxy S3 Android OS 4.1.2. And this is also strange.
Do you have any idea why this is happening?
When I start a new Activity inside of button listener like this:
ActivityA.java (MesajlarListViewActivity)
public class MesajlarListViewActivity extends TrackedActivity {
Context context = null;
// contacts JSONArray
JSONArray contacts = null;
ArrayList<Message> productArray = new ArrayList<Message>();
private ProductAdapter adapter;
private ListView productList;
private Runnable viewOrders;
private HoloProgressIndicator profilInfoProgress = null;
ImageView kapatButton = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mesajlar_list);
context = this;
kapatButton = (ImageView) findViewById(R.id.kapat_button);
/* kapat button onclick listener. */
// =================================================================================================================
kapatButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
// Set vibration on touch.
KnetGenericClass.vibratePhone(context);
finish();
}
});
// =================================================================================================================
//Progress bar.
profilInfoProgress = (HoloProgressIndicator) findViewById(R.id.profil_info_progress);
// cheking internet connectivity.
if(KnetGenericClass.checkInternetConnection(context))
{
// start task!
/* internet var ise web service baglantisi kurmaya baslayabiliriz. */
startActivityIndicatorWithThread();
}
else
{
KnetGenericClass.printErrorMessage(context, "Bağlantı Hatası",
"Lütfen internet bağlantınızı kontrol ediniz.");
}
productList = (ListView) findViewById(R.id.product_list);
adapter = new ProductAdapter(this, R.layout.message_row, productArray);
productList.setAdapter(adapter);
// When user click a view on list view new page is appearing.
productList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
// Set vibration on touch.
KnetGenericClass.vibratePhone(context);
/* Navigate to message detay activity class with ilan ID. */
Intent myIntent = new Intent(view.getContext(), MesajDetayActivity.class);
myIntent.putExtra("messageID", productArray.get(position).getId());
startActivity(myIntent);
// setting image of clicked message null.
RelativeLayout relativeLayout = (RelativeLayout) view;
ImageView unreadedImageView = (ImageView) relativeLayout.findViewById(R.id.unreaded_image);
unreadedImageView.setImageResource(0);
}
});
}
public class ProductAdapter extends ArrayAdapter<Message> {
ArrayList<Message> items;
public ProductAdapter(Context context, int textViewResourceId, ArrayList<Message> objects) {
super(context, textViewResourceId, objects);
this.items = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(convertView == null)
{
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.message_row, null);
}
ImageView unreadedImageView = (ImageView) convertView.findViewById(R.id.unreaded_image);
TextView productName = (TextView) convertView.findViewById(R.id.product_name);
TextView productDetail = (TextView) convertView.findViewById(R.id.product_detail);
// TextView productDate = (TextView)
// convertView.findViewById(R.id.product_date);
TextView sentDate = (TextView) convertView.findViewById(R.id.product_date);
productName.setText(items.get(position).getSender());
productDetail.setText(items.get(position).getTitle());
// String bodyNoHTML = items.get(position).getBody();
if(items.get(position).getIsReaded())
{
unreadedImageView.setImageResource(0);
}
else
{
unreadedImageView.setImageResource(R.drawable.bluedot);
}
String dateStr = items.get(position).getSentDate();
try
{
sentDate.setText(dateStr.substring(6, 8) + "." + dateStr.substring(4, 6) + "." + dateStr.substring(0, 4)
+" "+dateStr.substring(8, 10)+":"+dateStr.substring(10, 12));
}
catch(Exception e)
{
sentDate.setText("");
}
return convertView;
}
}// #end of product adapter class.
/* web service'e baglanti kurulan methodu threadin icerisinde cagiriyoruz. */
public void startActivityIndicatorWithThread()
{
// ==============================================================================================
// getting ilan details into arraylist.
// setting up thread.
viewOrders = new Runnable() {
public void run()
{
getMessageListFromWebService();
}
};
Thread thread = new Thread(null, viewOrders, "MagentoBackground");
thread.start();
profilInfoProgress.start();
// ==============================================================================================
// #end of the thread declaration.
}
public void getMessageListFromWebService()
{
// Creating JSON Parser instance
JSONParser jParser = new JSONParser(context);
// getting JSON string from URL
JSONArray jsonArray = jParser.getAuthorizedInfoFromUrlToJSONArray(
WebServiceInfo.getKnetWebServiceLink()+"/API/Member/GetInboxMessageList", MainActivity.getAccessToken());
// if json is null then there is a problem.
if(jsonArray == null)
{
// if json array is null then print error message.
runOnUiThread(showAlertMessage);
runOnUiThread(returnRes);
return;
}
try
{
// Eger aranilan kritere gore ilan yok ise hata mesaji basiyoruz.
if(jsonArray.length() == 0)
{
// if json array is null then print error message.
runOnUiThread(showAlertIlanYokMessage);
runOnUiThread(returnRes);
return;
}
// looping through All Contacts
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject c = jsonArray.getJSONObject(i);
// Storing each json item in variable
// String id = c.getString(TAG_ID);
String id = c.getString("Id");
String sender = c.getString("Sender");
// String body = c.getString("Body");
String title = c.getString("Title");
String sentDate = c.getString("SentDate");
Boolean isReaded = c.getBoolean("IsRead");
Message productObject = new Message(id, sender, "", title, sentDate, isReaded);
productArray.add(productObject);
}
}
catch (Exception e)
{
Log.e("BACKGROUND_PROC", e.getMessage());
}
runOnUiThread(returnRes);
}
// #end of thread.
private Runnable returnRes = new Runnable() {
public void run()
{
profilInfoProgress.stop();
adapter.notifyDataSetChanged();// refreshing data over adapter in
// list view.
}
};
// #end of thread.
private Runnable showAlertMessage = new Runnable() {
public void run()
{
// Bu hata genelde linkteki problemden, servera ulasilamamasindan
// veya timeouttan meydana gelir.
Toast.makeText(getApplicationContext(),
"Mesajlar alınamadı lütfen daha sonra tekrar deneyiniz.",
Toast.LENGTH_LONG).show();
}
};
private Runnable showAlertIlanYokMessage = new Runnable() {
public void run()
{
// Bu hata aranilan kelimeye gore ilan bulunamazsa gelir.
Toast.makeText(getApplicationContext(),
"Mesajlar bulunamadı.",
Toast.LENGTH_LONG).show();
}
};
}
========================================================================
ActivityB.java (MesajDetayActivity.java)
public class MesajDetayActivity extends TrackedActivity {
private HoloProgressIndicator profilInfoProgress = null;
TextView titleTextView = null;
TextView senderTextView = null;
TextView dateTextView = null;
WebView bodyWebView = null;
Message messageObject = null;
String messageID = null;
ImageView kapatButton = null;
Context context;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mesajdetaylari);
context = this;
kapatButton = (ImageView) findViewById(R.id.kapat_button);
/* kapat button onclick listener. */
// =================================================================================================================
kapatButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
// Set vibration on touch.
KnetGenericClass.vibratePhone(context);
finish();
}
});
// =================================================================================================================
//Progress bar.
profilInfoProgress = (HoloProgressIndicator) findViewById(R.id.profil_info_progress);
Bundle extras = getIntent().getExtras();
if(extras != null)
{
messageID = extras.getString("messageID");
}
titleTextView = (TextView) findViewById(R.id.title_textview);
senderTextView = (TextView) findViewById(R.id.sender_textview);
dateTextView = (TextView) findViewById(R.id.date_textview);
bodyWebView = (WebView) findViewById(R.id.mesaj_webView);
// Show the ProgressDialog on this thread
profilInfoProgress.start();
// Start a new thread that will download all the data
new MakeItTask().execute();
}
// Async task.
private class MakeItTask extends AsyncTask<String, Void, Object> {
protected Object doInBackground(String... args)
{
Log.i("MyApp", "Background thread starting");
// This is where you would do all the work of downloading your data
// getting message detay
/* connect to web service */
getMessageDetayFromWebService();
return null;
}
protected void onPostExecute(Object result)
{
// Pass the result data back to the main activity
// TakipListeActivity.this.data = result;
try
{
titleTextView.setText("Başlık: " + messageObject.getTitle());
senderTextView.setText("Gönderen: " + messageObject.getSender());
dateTextView.setText("Tarih: " + messageObject.getSentDate().substring(6, 8) + "."
+ messageObject.getSentDate().substring(4, 6) + "."
+ messageObject.getSentDate().substring(0, 4));
if(!messageObject.getBody().contains("img"))
{
bodyWebView.loadDataWithBaseURL(null, messageObject.getBody(), "text/html", "UTF-8", null);
}
}
catch (Exception e)
{
Log.e(CONNECTIVITY_SERVICE, "Mesaj Detayi bilgileri basilamadi.");
}
profilInfoProgress.stop();
}
}
/* web service'e baglanti kurulan methodu threadin icerisinde cagiriyoruz. */
public void getMessageDetayFromWebService()
{
// Creating JSON Parser instance
JSONParser jParser = new JSONParser(context);
// getting JSON string from URL
JSONObject jsonObject = jParser.getAuthorizedInfoFromUrlToJSONObject(
WebServiceInfo.getKnetWebServiceLink()+"/API/Member/GetInboxMessage/" + messageID, MainActivity.getAccessToken());
// if json is null then there is a problem.
if(jsonObject == null)
{
return;
}
try
{
String title = jsonObject.getString("Title");
String id = jsonObject.getString("Id");
String sender = jsonObject.getString("Sender");
String date = jsonObject.getString("SentDate");
String body = jsonObject.getString("Body");
messageObject = new Message(id, sender, body, title, date, true);
}
catch (Exception e)
{
Log.e("BACKGROUND_PROC", e.getMessage());
}
}// #end of getIlanDetayFromWebService.
}
Edit: Not only these two activities have this problem, all the activities acting same behavior on some phones.
Check to see whether Don't keep activities under Settings > System > Developer options > Apps is enabled or not.
The Activity documentation (http://developer.android.com/reference/android/app/Activity.html) says the following about the lifecycle of a background activity:
A background activity (an activity that is not visible to the user and has been paused) is no longer critical, so the system may safely kill its process to reclaim memory for other foreground or visible processes. If its process needs to be killed, when the user navigates back to the activity (making it visible on the screen again), its onCreate(Bundle) method will be called with the savedInstanceState it had previously supplied in onSaveInstanceState(Bundle) so that it can restart itself in the same state as the user last left it.
In other words, ActivityA may or may not be destroyed by the operating system while ActivityB is active, so this situation has to be handled in the code. If ActivityA has been destroyed, onCreate(Bundle) will be called, when the user presses the back button in ActivityB.
There's an Android developer setting called "Do not keep activities". The description for this option is "Destroy every activity as soon as the user leaves it." This sounds like a good description of what you're seeing, and since you're only seeing it on a few phones the idea that this is caused by a non-default system setting seems plausible.
Ideally your app would still work in this scenario, even if less optimally. But if this setting is a problem for your app, you may wish to document this problem for your users.
Have you tried changing the launchmode in the Android Manifest? Try adding this to your Activity declaration:
android:launchMode="singleTask"
Next, try using startActivityForResult, instead of startActivity. This will force Activity A to call its onActivityResult(int, int, Intent) method when Activity B finishes - which may skip this (buggy) call to onCreate. Then, in Activity A, implement the method to do something (such as printing a debug statement):
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.i("Test", "Did this work???");
//TODO send notification to your server to verify this works?
}
I do not see any problem in this behaviour.
In case you wish to preserve the state of ActivityA, make use of the methods onSaveInstanceState and onRestoreInstanceState. See Activity Lifecycle at http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle for more details.
See also https://stackoverflow.com/a/10492967/332210 for a deeper understanding.
You can try one thing provide your layout in onCreate() and do the rest of the work in onStart() ?? if it works??
LIKE:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show);
}
and
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i(TAG, "On Start .....");
}
See Activity Lifecycle
Perhaps you should use
Intent startIntent = new Intent(view.getContext(), ActivityB.class);
startActivity(startIntent);
finish() ;
And
Intent startIntent = new Intent(view.getContext(), ActivityA.class);
startActivity(startIntent);
finish() ;
each time you go back or forward.
It too faced the exact problem and solved issue by Using android:launchMode="standard" in activity of manifest.
Override onStart() and onResume method in Activity A and check if the problem is still persist. and if possible please give your activtiy A and B code here.
Activity A uses layout R.layout.mesajlar_list
Activity B uses layout R.layout.mesajdetaylari
But both have the following line of code:
kapatButton = (ImageView) findViewById(R.id.kapat_button);
Which layout is R.id.kapat_button in? Using the same id in different layouts is a very risky thing to do. I can't guarantee it's causing what you're seeing, but it is the sort of thing that may cause weird behaviour.
I think it is not because of memory the limit.
https://www.box.com/s/7pd0as03bb8wwumuc9l9
You should test these two activities and check whether it is happening in this example too or not. Please share your AndroidManifest.xml file content too, it will help with debugging.
I got this issue recently, and this make me annoyed. I think that issue around 2 options solution to check but useless.
About the setting "Don't keep activities" corrected here, I used this code to check that it optional checked or not (my test device customize base on version 2.3.5 and not show this option):
private boolean isAlwaysFinishActivitiesOptionEnabled() {
int alwaysFinishActivitiesInt = 0;
if (Build.VERSION.SDK_INT >= 17) {
alwaysFinishActivitiesInt = Settings.System.getInt(getApplicationContext().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0);
} else {
alwaysFinishActivitiesInt = Settings.System.getInt(getApplicationContext().getContentResolver(), Settings.System.ALWAYS_FINISH_ACTIVITIES, 0);
}
if (alwaysFinishActivitiesInt == 1) {
return true;
} else {
return false;
}
}
Result check is false in my case. I also check the memory when running application and it nothing occur.
you can use android:launchMode="singleTop"in manifest.
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

AsyncTask displaying progress bar

I am very new to android. I got two activities A, B . Activity A parse the data from the sever and iterate through the levels. and calls the activity B through intent. Activity B takes some time to display the data so I am trying to display the progress bar. Here is my code.
public class Display extends Activity {
ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.attributequestions);
new asynctask().execute();
}
class asynctask extends AsyncTask<Context,Void,Void>{
Survey[] surveyque=null;
// i hace created seperated class forsurvey that has info about data
String list[];
private ProgressDialog Dialog;
#Override
protected void onPreExecute()
{
Dialog=ProgressDialog.show(Display.this, "Parsing Data", "Please wait..........");
}
#Override
protected void onPostExecute(Void unused)
{
try
{
if(Dialog.isShowing())
{
Dialog.dismiss();
}
Intent intent=getIntent();
}
catch(Exception e)
{
Log.d("Onsitev4", "error");
}
}
#Override
protected Void doInBackground(Context... params) {
try {
LinearLayout layout1 = (LinearLayout) findViewById(R.id.linearLayout1);
//getting exception here. I dont understant why
// I have declared layout params and displaying activities in another class
ButtonView c = new ButtonView();
c.layout=layout1;
c.context =getBaseContext();
DbCoreSqlSurveys surveys=new DbCoreSqlSurveys(getBaseContext());
Document doc =surveys.getSurveySet();
surveyquestions= GetSurveyLevels(doc,c );
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
}
return null;
}
}
public SurveyObject[] GetSurveyLevels(Document doc, ButtonView c) {
NodeList nlQuestions = doc.getElementsByTagName("Survey");
SurveyObject[] allsurveys = new SurveyObject[nlQuestions.getLength()];
for (int i = 0; i < nlQuestions.getLength(); i++){
Node survey = nlQuestions.item(i);
String f =survey.getNodeName();
Log.d("OnsiteV4", "survey " + f);
NodeList surveyChildNodes = survey.getChildNodes();
SurveyObject s=new SurveyObject();
for (int j = 0; j < surveyChildNodes.getLength(); j++){
Node surveyChild = surveyChildNodes.item(j);
String h =surveyChild.getNodeName();
Log.d("OnsiteV4", "survey child node = " + h);
if (h !="#text"){
Surveys t = Surveys.valueOf(h);
switch(t){
case KeySurvey:
s.KeySurvey=surveyChild.getTextContent();
displaySurveyLink(s.SurveyDescription,"",c,0,s.SurveyDescription,"","","","");
break;
case SurveyDescription:
s.SurveyDescription=surveyChild.getTextContent();
displaySurveyLink(s.SurveyDescription,"",c,0,s.SurveyDescription,"","","","");
break;
case SurveyUserCode:
s.SurveyUserCode=surveyChild.getTextContent();
break;
case Level1:
if(surveyChild.hasChildNodes()){
s.Level1= processLevel1Nodes(surveyChild,c,s.SurveyDescription);
}
break;
default:
break;
}
}
allsurveys[i]=s;
}
}
return allsurveys;
}
// methods iterating through levels that is not showed
private void displaySurveyLink(final String description, String tag, ButtonView c, int indentation, final String surveyDescription, final String level1description, final String level2description, final String level3description, final String level4description)
{
if (description == null || tag == null){
return;
}
final TextView tv = c.addButton(description,tag,indentation);
tv.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
final Intent intent = new Intent();
intent.setClass(v.getContext(),ActivityB.class);
intent.putExtra("KeyLevel",tv.getTag().toString());
intent.putExtra("SurveyDescription",surveyDescription);
intent.putExtra("level1description",level1description);
intent.putExtra("level2description",level2description);
intent.putExtra("level3description",level3description);
intent.putExtra("level4description",level4description);
intent.putExtra("Description",description);
if (tv.getTag() != null){
if (tv.getTag().toString() != ""){
startActivity(intent);
}
}
}
});
}
}
I am getting exception in doinbackground. I am confused . please help me..
You are getting an exception because you are accessing UI elements on a non-UI thread. The main thread that the application creates is the UI thread, and that's where all of your visual elements are created and therefore the only thread in which you should access them.
To appropriately use AsyncTask, you run your long-running operations in doInBackground, and you use onPreExecute, onPostExecute and onProgressUpdated to work with the UI (show/hide progress dialogs, update views, etc). Whenever I use an AsyncTask and I want to show progress, I override onProgressUpdated giving it parameter type Integer and I call publishProgress from doInBackground. This would require a change of the base class signature from AsyncTask<Context,Void,Void> to AsyncTask<Context,Integer,Void>. You can use other object types for this as well...I just use Integer as an example if you want to show the percentage of the task that is complete, for example.
It's becoz your code should throwing exception as you are doing UI stuff in the doinbackgound of asyc task. Please remove all the UI related work from doingbackgound method.

Categories

Resources