I am working on an android app development and I am stuck in an issue. I have used ANSYNC TASK method but now it has stopped working.
It was working fine from last many years but now it is creating problem.
Also, doinbackground() and postExecute() methods are not working (they are not called) only preExecute() method is working for me.
I am attaching code here for the reference:
class MyAsyncTask extends AsyncTask<Void, ConversationModel, Void> {
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
heading.setText("myheading");
}
});
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (ConversationModel model : dataList) {
if (flagStop)
break;
publishProgress(model);
long_time = Long.parseLong(model.sound_time) * 1000 + 500;
try {
Thread.sleep(long_time);
Thread.sleep(long_extraTime);
long_extraTime = 0;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
Log.d("i", i + " -----------------");
}
return null;
}
protected void onProgressUpdate(ConversationModel... model) {
if (i % 2 == 0) {
View v = View.inflate(Conversation1.this, arrInt_resource[0], null);
v.setAnimation(null);
TextView txtV_spn = (TextView) v.findViewById(R.id.textView_spn);
TextView txtV_eng = (TextView) v.findViewById(R.id.textView_eng);
ImageView img_sound = (ImageView) v.findViewById(R.id.imgsound_conv_spn2eng);
RelativeLayout speak_layout = (RelativeLayout) v.findViewById(R.id.speaking_layout);
heading.setText(dataList.get(0).heading);
if (flag != 1) {
txtV_spn.setText(model[0].eng_txt);
txtV_eng.setText(model[0].spn_txt);
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (i >= dataList.size()) {
Log.d("i", i + " ------------------");
makingcontinueImageView();
}
}
}
i think you are using .execute() method of asynctask to start execute of asynctask, change that line of code with this one
asynctask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Related
My purpose is simple,I want to creat a countdown that count from 10 to 1.I have tried using countdown given by google but I can't make it as a thread,so I use this way to creat the same function but I had a problem with this code.My app getting crashed when I use this threads code.Please help me man.
public class MainActivity extends Activity {
TextView textView;
Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
String string = textView.getText().toString();
int num = Integer.parseInt(string);
num = num-1;
string = Integer.toString(num);
textView.setText(string);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Thread myThread = new Thread(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
for(int i = 10; i>0;i--){
try {
Thread.sleep(1000);
//handler.sendMessage(handler.obtainMessage());
handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
myThread.start();
}
}
Your problem isnt with the thread, its with these lines
String string = textView.getText().toString();
int num = Integer.parseInt(string);
You probably have that textView starting out with some text in the XML("Large Text"). Remove it. "Large Text" isn't a number, so when you call parseInt() on that original string its trying to convert "Large Text" to a number.
Try this code:
try {
String string = textView.getText().toString();
int num = Integer.parseInt(string);
textView.setText(String.valueOf(--num));
catch(NumberFormatException ignored){
}
with a try/catch block
It is stated in d.android.com for onPreExecute() that it runs on the UI thread before doInBackground(Params...) so it should easily access the TextView and perform setText() method from the Activity from which it was executed().
But here in the below codes the loading TextView is privately declared inside the class SplashScreen that extends Activity. Inside the onCreate() it is linked with the TextView widget of the UI. But when AsyncTask extended class Atom the function onPreExecute() is executed which throws a NullPointerExcepction for the statement loading.setText("Loading..."); executed inside it.
Here the code
public class SplashScreen extends Activity implements AnimationListener{
...
TextView loading=null;
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
try {
a = (Atom) new Atom().execute(null,null,null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
finish();
}
...
loading = (TextView) findViewById(R.id.textView2);
....
}
public class Atom extends AsyncTask<RSSFeed, Void, RSSFeed>{
private RSSReader reader;
private RSSFeed feed = null;
private String uri = "http://website.com/feed/";
#Override
protected void onPreExecute() {
super.onPreExecute();
//------------problem----area-------------------
loading.setText("Loading...");
//------------problem----area-------------------
}
#Override
protected RSSFeed doInBackground(RSSFeed... arg0) {
reader = new RSSReader();
try {
feed = reader.load(uri);
Log.d("rss", feed.getTitle());
} catch (RSSReaderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return feed;
}
#Override
protected void onPostExecute(RSSFeed result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
prg.cancel();
t(result.getTitle().toString());
}
}
}
The stack:
03-09 10:50:12.793: W/System.err(14214): java.lang.NullPointerException
03-09 10:50:12.813: W/System.err(14214): at in.edu.ss.er.splash.SplashScreen$Atom.onPreExecute(SplashScreen.java:158)
03-09 10:50:12.827: W/System.err(14214): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
03-09 10:50:12.833: W/System.err(14214): at android.os.AsyncTask.execute(AsyncTask.java:534)
03-09 10:50:12.833: W/System.err(14214): at in.edu.ss.er.splash.SplashScreen.onCreate(SplashScreen.java:45)
Try to initialize TextView before executing asyntask. Like following.
try {
loading = (TextView) findViewById(R.id.textView2);
a = (Atom) new Atom().execute(null,null,null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
finish();
}
I don't know this is correct or not, This my guessing, So, Please let me know what happened.
Thanks
just initialize your text view before calling AsyncTask. do something like this
loading = (TextView) findViewById(R.id.textView2);
try {
a = (Atom) new Atom().execute(null,null,null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
finish();
}
You have to initialize your textview before then call asynctask. Change your code into following-
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
loading = (TextView) findViewById(R.id.textView2);
try {
a = (Atom) new Atom().execute(null,null,null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
finish();
}
}
I am using Jsoup to parse a part of a website and then put it into a string. I want to visualize this string into a textView, but since only the thread that had created the textView can modify it i need to pass the value of the string into the main thread. how?
This is the code: (ignore the tabhost stuff)
public class NewsAndAnnouncements extends Activity {
TabHost host;
FlyOutContainer container;
Button bttoggle;
Button bt1;
String loggity;
TextView tv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.container = (FlyOutContainer) this.getLayoutInflater().inflate(
R.layout.newsandannouncements, null);
this.setContentView(container);
host = (TabHost) findViewById(R.id.tabhost);
host.setup();
TabSpec specs = host.newTabSpec("TAGGITY EINZ");
specs.setContent(R.id.tab1);
specs.setIndicator("News");
host.addTab(specs);
specs = host.newTabSpec("TAGGITY ZWEI");
specs.setContent(R.id.tab2);
specs.setIndicator("Notices");
host.addTab(specs);
specs = host.newTabSpec("TAGGITY DREI");
specs.setContent(R.id.tab3);
specs.setIndicator("Events");
host.addTab(specs);
tv1 = (TextView) findViewById(R.id.textView1);
/*
* bttoggle = (Button) findViewById(R.id.bttoggle); bt1 = (Button)
* findViewById(R.id.Button1);
*
* bttoggle.setOnClickListener(new OnClickListener() {
*
* #Override public void onClick(View v) { // TODO Auto-generated method
* container.toggleMenu(); } });
*
* bt1.setOnClickListener(new OnClickListener() {
*
* #Override public void onClick(View v) { // TODO Auto-generated method
* container.toggleMenu(); } });
*/
Thread newsThread = new Thread() {
public void run() {
Document doc = null;
try {
doc = Jsoup
.connect(
"http://acs.bg/Home/About_ACS/News_and_Events/News.aspx")
.get();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Elements myin = doc.getElementsByClass("news_list");
loggity = myin.toString();
Log.i("ELEMENTS HTML", loggity);
}
};
newsThread.start();
tv1.setText(loggity);
}
}
Try using AsyncTask instead of the Thread. To modify views on your ui thread use the runOnUiThread() method in your activity.
runOnUiThread(new Runnable() {
#Override
public void run() {
tv1.setText("...");
}
});
Use an AsyncTask instead of a raw Thread:
new AsyncTask<URL, Object, Document>() {
protected Document doInBackground(URL... urls) {
// parse URL and return document
}
protected void onPostExecute(Document result) {
// this runs in UI thread
// show document in UI
}
}).execute(myURL);
There are two ways to d it-
1)- Using AsyncTask
2)- Using Handler
Thread newsThread = new Thread()
{
public void run()
{
Document doc = null;
try {
doc = Jsoup
.connect(
"http://acs.bg/Home/About_ACS/News_and_Events/News.aspx")
.get();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Elements myin = doc.getElementsByClass("news_list");
loggity = myin.toString();
mHandler.post(new Runnable()
{
#Override
public void run()
{
try
{
tv1.setText(loggity);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
Log.i("ELEMENTS HTML", loggity);
}
};
newsThread.start();
You can initialize the Hanlder in the start.
try this sample code, don't know if this is the better way:
public class MainThread {
public static void main(String args[]) {
Thread2 t2 = new Thread2();
Thread nextThread = new Thread(t2);
nextThread.start();
try {
nextThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println();
System.out.println(t2.getStr());
}
private static class Thread2 implements Runnable{
private String str;
#Override
public void run() {
setStr("T2 Thread String");
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
}
I am trying to show error messages and hide them after 3 seconds. That's what I have written but it seems that it doesn't work that way.
yazi.setVisibility(View.VISIBLE);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
yazi.setVisibility(View.GONE);
You can use a Handler with its postDelayed method for your purpose:
//Show your view
yazi.setVisibility(View.VISIBLE);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Hide your View after 3 seconds
yazi.setVisibility(View.GONE);
}
}, 3000);
Update your code like this
Inside your onCreate() method
yazi.setVisibility(View.VISIBLE);
Thread thread=new Thread(runnable);
thread.start();
and outside your onCreate() method , do like this
Runnable runnable=new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
yazi.setVisibility(View.GONE);
}
});
}
};
};
Always use runOnUiThread for making UI operations.
I'm trying to retrieve the TextBox value when I press the button, but it does not work. Here is my code. Any idea?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.httpxml);
httpstuff = (TextView) findViewById(R.id.http);
client = new DefaultHttpClient();
button = (Button)findViewById(R.id.shoppingprice);
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
//shoppingapi price = new shoppingapi();
et=(EditText)findViewById(R.id.text);
txt=et.getText().toString();
}
});
new Read().execute("displayprice");
}
#SuppressLint("ShowToast")
public JSONObject productprice(String productname) throws ClientProtocolException,IOException,JSONException
{
StringBuilder url = new StringBuilder(URL);
url.append(productname);
url.append("&searchType=keyword&contentType=json");
HttpGet get = new HttpGet(url.toString());
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
Log.d("Price", "asdasd");
if(status == 200){
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
jObj = new JSONObject(data);
JSONObject jsonData = jObj.getJSONObject("mercadoresult");
JSONObject jsonProducts = jsonData.getJSONObject("products");
JSONArray jsonArray = jsonProducts.getJSONArray("product");
jsonArray = (JSONArray) jsonArray.get(1);
jObj = (JSONObject)jsonArray.get(0);
return jObj;
}
else
{
Toast.makeText(MainActivity.this,"error",Toast.LENGTH_LONG).show();
return null;
}
}
public class Read extends AsyncTask<String,Integer,String>
{
#Override
protected String doInBackground(String... params) {
try {
json = productprice(txt);
return json.getString("displayprice");
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
// TODO Auto-generated method stub
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
//super.onPostExecute(result);
//httpstuff.setText("The price of the Product is ");
httpstuff.setText(result);
httpstuff.setText(txt);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
It shows no error but it shows txt value as blank
Because you are calling this line
new Read().execute("displayprice");
in onCreate
Where as txt value is changing when you click on button.
So you are accessing txt value before assigning it. if you want to use the value change like this and try like this
public void onClick(View arg0) {
et=(EditText)findViewById(R.id.text);
txt=et.getText().toString();
new Read().execute("displayprice");
}
});
Reference it outside Button click.
et=(EditText)findViewById(R.id.text);
Access directly inside AsynTask shown below
public class Read extends AsyncTask<String,Integer,String>
{
String txt = et.getText().toString();
#Override
protected String doInBackground(String... params) {
try {
json = productprice(txt);
return json.getString("displayprice");
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
// TODO Auto-generated method stub
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
//super.onPostExecute(result);
//httpstuff.setText("The price of the Product is ");
httpstuff.setText(result);
httpstuff.setText(txt);
}
}