I Can't use findViewById() from my Kclass=( How can i use it? `
private class BackGroundTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
try {
//execute - means sending
response =httpClient.execute(request);
HttpEntity entity=response.getEntity();
String str=EntityUtils.toString(entity);
Log.v("Json=", str);
//adding new response to our Response Class
resp.addNewResponse(str);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
Log.e(TAG, "Exception caught: ", e);
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
httpClient.getConnectionManager().shutdown();
TextView textView = (TextView) findViewById(R.id.textView1);
textView.setText("Done");
}
}
}
please write an exact code. This class is in another .java file. Not in MainActivity.java
The easiest way would be to not use findViewById() at all since you are in a separate file and that is an Activity method.
You can simply use an interface to create a callback in onPostExecute() and send back the String result to your Activity. Then in your callback you can simply set the text as you wish.
This answer gives an example of using an interface with AsyncTask
You may pass Activity context(YourActivity.this) to your AsyncTask and use activity.findViewById(...);
EDIT
Some code:
Add to AsyncTask:
private Activity mActivity;
public YourAsyncTask(Activity activity){
this.mActivity = activity
}
...
....
protected void onPostExecute(Void result) {
super.onPostExecute(result);
httpClient.getConnectionManager().shutdown();
if(mActivity!=null){
TextView textView = (TextView) mActivity.findViewById(R.id.textView1);
}
textView.setText("Done");
}
private Activity activity;
and in constructor:
public BackGroundTask(Activity activity){
this.activity=activity;
}
and in post Execute:
protected void onPostExecute(Void result) {
super.onPostExecute(result);
httpClient.getConnectionManager().shutdown();
TextView textView = (TextView) activity.findViewById(R.id.textView1);
textView.setText("Done");
}
If creating new background class from activity class call:
BackGroundTask doItInBackGround = new BackGroundTask(this);
If in a click listener or any class inside Activity call:
BackGroundTask doItInBackGround = new BackGroundTask(ActivityName.this);
Related
Am getting exception when the user continuously clicking the button on which am calling the async task.
So is there any way to cancel the execution of first async task execution on second time pressing the button.
I hope u understand the problem.
The codes am using is given below.
On button click am using the following code
GetData obj= new GetData();
String urls="http://pathramonline.com/?cat=46";
obj.execute(urls);
My async task
public class GetData extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
BufferedReader reader =null;
String data =null;
try{
HttpClient client = new DefaultHttpClient();
URI uri=new URI(params[0]);
HttpGet get =new HttpGet(uri);
HttpResponse response= client.execute(get);
InputStream stream=response.getEntity().getContent();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer =new StringBuffer("");
String line="";
String newLine= System.getProperty("line.separator");
while((line=reader.readLine())!=null){
buffer.append(line+newLine);
}
reader.close();
data = buffer.toString();
return data;
}
catch(URISyntaxException e){
e.printStackTrace();
}
catch(ClientProtocolException f){
f.printStackTrace();
}
catch(IOException g){
g.printStackTrace();
}
catch(Exception e)
{
//
}
finally{
if(reader!=null){
try{
reader.close();
}
catch(Exception e){
}
}
}
return null;
}
#Override
protected void onCancelled() {
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//TextView t3=(TextView)findViewById(R.id.textView3);
if(result==null)
{
Intent home = new Intent(MainActivity.this,NoConnection.class);
MainActivity.this.startActivity(home);
MainActivity.this.finish();
}
//Some actions
}
}
I would suggest another method instead of cancelling the asynctask.
In your onPreExecute() method disable the button click
button.setEnabled(false);
And in onPostExecute() method enable back the button
button.setEnabled(true);
If you explicitly want to know that button is disabled then while the asynctask is being executed you can change the background color of the button to another color or background, so that the user will know that some function is being carried out and he needs to wait..
Another approach is
new AsyncTask<Void, Void, Void>() {
String result = "";
ProgressDialog progressDialog = null;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Loading , Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
String url = "your link comes here"
JSONObject jsonObject = jpass.getJSONFromUrl(url);
try {
//do your work here
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void a) {
// TODO Auto-generated method stub
progressDialog.dismiss();
if (result.equals("success")) {
//on success do some work here
}
else
{
//on failure do some work here
}
super.onPostExecute(a);
}
}.execute();
Instead of cancelling the AsyncTask just set your button's click listener to null and then again set it inside onPostExecute of your AsyncTask. It would be even better if you display a ProgressBar when your doInBackground() code is executing.
I try to do app which show elements. Each element should start showing when the before element was hidden. Each element is showing 2 seconds. I try a lot of way:
Android/java - How to do that loop wait to do action
And now I try with Asynctask. I find a way:
public class MainActivity extends Activity
{
ImageView image1,image2;
int id = 0;
AsyncTask.Status status;
TextView txt;
String status1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LongOperation task = new LongOperation();
status = task.getStatus();
status1 = String.valueOf(status);
txt = (TextView) findViewById(R.id.txt);
image1 = (ImageView)findViewById(R.id.image1);
image2 = (ImageView)findViewById(R.id.image2);
do{
new LongOperation().execute("");
id=id+1;
txt.setText(status1);
try
{
try
{
task.get(2500, TimeUnit.MILLISECONDS);
} catch (TimeoutException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}while(id<3);
}
private class LongOperation extends AsyncTask<String, Void, String>
{
#Override
protected void onPreExecute()
{
image1.setVisibility(View.VISIBLE);
image2.setVisibility(View.VISIBLE);
txt.setText(status1);
}
#Override
protected String doInBackground(String... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.interrupted();
}
return null;
}
#Override
protected void onPostExecute(String result) {
txt.setText("Executed");
image1.setVisibility(View.GONE);
image2.setVisibility(View.GONE);
}
#Override
protected void onProgressUpdate(Void... values) {}
}
(This is a example). App run and end after 7.5 sec (everything ok) but images aren't shown when I start. What should I do?
I think you are creating a deadlock situation with your threads. The main UI thread is blocking at the line task.get(), which in turn is preventing the AsyncTask from running properly; its onPreExecute method is posted onto the UI Thread, and the doInBackground doesn't run until onPreExecute completes.
I know that have a lot of answers about this, but I can't find exactly what I need:
1) When users click on the button, shows a progress Dialog;
2) Executes a class AsyncTask and wait for the answer (it's a response using HTTPUrlConnection);
3) Dismiss Progress Dialog;
I tried a lot of things, but the progress dialog is not "appearing". My code:
public class MainActivity extends Activity implements OnTaskCompleted{
..
private ProgressDialog progressDialog;
private Button btnLogin;
..
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
progressDialog = ProgressDialog.show(MainActivity.this,
"", "Scanning Please Wait", true);
try {
String param1 = "testParam1";
String param2 = "testParam2";
String response = new SyncHelper(MainActivity.this).execute("http://server.example.com/api", param1, param2).get(); //this way, my activity waits of the answer
Log.d(TAG, "Finished: " + response);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
// user didn't entered username or password
Toast.makeText(getApplicationContext(),
"Done",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
}
}
});
}
public void onTaskCompleted()
{
progressDialog.dismiss();
}
public class SyncHelper extends AsyncTask<Object, Void, String>
{
..
private OnTaskCompleted listener;
..
protected String doInBackground(Object... url) {
String response = "";
try {
response = getRequest((String) url[0],(String) url[1], (String) url[2]); //Here I make a HttpURLConnection
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
#Override
protected void onPreExecute() {
}
protected void onPostExecute(String result) {
listener.onTaskCompleted();
}
}
public interface OnTaskCompleted{
void onTaskCompleted();
}
public class MainActivity extends Activity{
..
private Button btnLogin;
..
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
try {
String param1 = "testParam1";
String param2 = "testParam2";
new SyncHelper(MainActivity.this).execute("http://server.example.com/api", param1, param2); //this way, my activity waits of the answer
Log.d(TAG, "Finished: " + response);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
// user didn't entered username or password
Toast.makeText(getApplicationContext(),
"Done",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
}
}
});
}
public class SyncHelper extends AsyncTask<String, Void, String>
{
..
Context context;
private ProgressDialog pd;
..
public SyncHelper (Context c)
{
context = c;
}
#Override
protected void onPreExecute() {
pd = new ProgressDialog(context);
pd.setTitle("Processing...");
pd.setMessage("Please wait.");
pd.setCancelable(false);
pd.setIndeterminate(true);
pd.show();
}
protected String doInBackground(String... url) {
String response = "";
try {
response = getRequest(url[0], url[1], url[2]); //Here I make a HttpURLConnection
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
protected void onPostExecute(String result) {
// here you will be getting the response in String result.
if (pd.isShowing())
pd.dismiss();
}
}
When you are using get, using AsyncTask doesn't make any sense. Because get() will block the UI Thread, maybe thats why are not able to see the progress dialog. If you want to send the response back to the MainActivity then use the callback interface as you were using beofre.
I read and apply something from this link:How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class? but I get an error NullPointerException onPostExecute on the line delegate.processFinish(result); What is the problem in my code? Here is the code:
public class MainActivity extends Activity implements AsyncResponse{
ProductConnect asyncTask =new ProductConnect();
public void processFinish(String output){
//this you will received result fired from async class of onPostExecute(result) method.
Log.v(TAG, output);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
asyncTask.delegate = this;
setContentView(R.layout.activity_main);
Button b = (Button) findViewById(R.id.button1);
final Intent i=new Intent(MainActivity.this, second.class);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new ProductConnect().execute(true);
startActivity(i);
//startActivity(new Intent(MainActivity.this, second.class));
}
});
}
// START DATABASE CONNECTION
class ProductConnect extends AsyncTask<Boolean, String, String> {
public AsyncResponse delegate=null;
private Activity activity;
public void MyAsyncTask(Activity activity) {
this.activity = activity;
}
#Override
protected String doInBackground(Boolean... params) {
String result = null;
StringBuilder sb = new StringBuilder();
try {
// http post
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://192.168.2.245/getProducts.php");
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() != 200) {
Log.d("MyApp", "Server encountered an error");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF8"));
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
Log.d("test", result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
return result;
}
#Override
protected void onPostExecute(String result) {
try {
JSONArray jArray = new JSONArray(result);
JSONObject json_data;
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
t = json_data.getString("name");
delegate.processFinish(result);
}
} catch (JSONException e1) {
e1.printStackTrace();
} catch (ParseException e1) {
e1.printStackTrace();
}
super.onPostExecute(result);
}
protected void onPreExecute() {
super.onPreExecute();
ProgressDialog pd = new ProgressDialog(MainActivity.this);
pd.setTitle("Lütfen Bekleyiniz");
pd.setMessage("Authenticating..");
pd.show();
}
}
You initialize your variable to null
public AsyncResponse delegate=null;
so naturally it will give NPE when you try to use it. You give it a value in your Activity so you could pass that to the constructor of your AsyncTask and initialize it to that object.
Your are starting a new AsyncTask in this line:
new ProductConnect().execute(true);
you should execute your asyncTask change that line with this:
asyncTask.execute(true);
I think the best way to do this is using interfaces.. Create a listener for this.
[]'s
you can access asynctask() method when creating new object from it.
sample:
LoginSyncProvider syncProvider = (LoginSyncProvider) new LoginSyncProvider(){
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//TODO write something here
}
}
}.execute();
You've to pass context to that AsyncTask.
Then, on postExecute, cast context to your Activity.
Example:
((MyActivity)context).doSomethingWithResults(resultOfAsyncTask);
Edit:
Your Activity:
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
new MyAsyncTask(this).execute();
}
public void sayHello(String name){
Log.d("log","hello "+name+"!!!");
}
}
Your asynctask:
class MyAsyncTask extends AsyncTask<String,String,String>{
Context context;
public AutoPassarImatges(Context cont) {
super();
this.context = cont;
// TODO Auto-generated constructor stub
}
#Override
protected String doInBackground(String... params) {
[.......]
return null;
}
#Override
protected void onPostExecute(String result) {
((MyActivity)context).sayHello(result);
}
}
I have the following class:
class CargaImgsParaAmpliar extends AsyncTask<Void, Void, Bitmap> {
final ProgressDialog progressDialog = new ProgressDialog(imagen.this);
protected void onPreExecute() {
progressDialog.setTitle("");
progressDialog.setMessage("Cargando Imagen...");
progressDialog.show();
}
protected Bitmap doInBackground(Void... params) {
Bitmap mIcon1 = null;
URL url_value;
try {
url_value = new URL(StrUrl);
mIcon1 = BitmapFactory.decodeStream(url_value.openConnection().getInputStream());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mIcon1;
}
protected void onPostExecute(Bitmap imagen) {
m_imageView.setImageBitmap(urlImageToBitmap(StrUrl));
progressDialog.dismiss();
}
}
I am doing internet discharge processes within AsyncTask and it still gives me the exception android.os.NetworkOnMainThreadException.
How can I fix this isse?
It seems to me that urlImageToBitmap accesses the network but is executed from onPostExecute (which is run on the UI task).
And you don't seem to be doing anything with imagen parameter in onPostExecute. So the image retrieved in doInBackground is basically lost.