I have used AsyncTask with Activity, And it gave me desired result without any failure.
Now I need to use AsyncTask with Fragments. In Fragments AsyncTask is not updating UI. I got an answer here. I tried that logic in my code but still I'm not able to update UI after getting response from servlet. Your help will be very appreciated.
Code what I have tried:
public class FragmentMyProfile extends Fragment
{
TextView txtViewUserFullName;
SharedPreferences shrdPref;
String currentUserFirstName = "", currentUserEmail = "";
String URL = "http://10.0.2.2:8080/iGnite_Survey/GetUserDetailsServlet";
String jsonObjectReceivedFromServer = "";
public FragmentMyProfile()
{
// empty constructor required for fragment subclass
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_my_profile, container, false);
shrdPref = rootView.getContext().getSharedPreferences("shrdPref", Context.MODE_PRIVATE);
txtViewUserFullName = (TextView) rootView.findViewById(R.id.textViewUserFullName);
//get current user first name, default value is ""
currentUserFirstName = shrdPref.getString(String.valueOf(R.string.curentLoggedInUserFirstName), "");
currentUserEmail = shrdPref.getString(String.valueOf(R.string.curentLoggedInUserEmail), "");
//display current user first name
if(!currentUserFirstName.equals(""))
{
txtViewDisplayUserFirstName.setText("Welcome "+currentUserFirstName);
}
else
{
txtViewDisplayUserFirstName.setText(String.valueOf(R.string.welcomeUser));
}
//get all user details from server
GetUserDetailsAsyncTask getUserDetailsAsyncTask = new GetUserDetailsAsyncTask (new FragmentCallback()
{
#Override
public void onTaskDone(String output)
{
//txtViewUserFullName.setText(output);
}
});
getUserDetailsAsyncTask.execute(new String[] { URL });
return rootView;
}
public interface FragmentCallback
{
public void onTaskDone(String output);
}
//------------------------------------------------------------------------------
public class GetUserDetailsAsyncTask extends AsyncTask<String, Void, String>
{
private FragmentCallback mFragmentCallback;
public GetUserDetailsAsyncTask (FragmentCallback fragmentCallback)
{
mFragmentCallback = fragmentCallback;
}
#Override
protected String doInBackground(String... urls)
{
String output = null;
for (String url : urls)
{
output = sendDataToServer(url);
}
return output;
}
#Override
protected void onPostExecute (String output)
{
super.onPostExecute(output);
mFragmentCallback.onTaskDone();
txtViewUserFullName.setText("output");
}
private String sendDataToServer(String url)
{
String output = null;
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("user_email", currentUserEmail));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity httpEntity = response.getEntity();
output = EntityUtils.toString(httpEntity);
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return output;
}
}
}
You have to use the inter-fragment communication concept to update the UI Thread from the fragment asynctask i.e INTERFACE
Please refer this tutorial with source code to understand it better : Handle Android AsyncTask Configuration Change Using Fragment
Related
I have a method name Request() in the onCreate method of the activity.
private void Request() {
new PostDataAsyncTask(textEmail, tValue).execute();
}
Iam passing two strings in it and the async class is as follows:
public class PostDataAsyncTask extends AsyncTask<String, String, String> {
GameActivity game= new GameActivity();
private String data,data1;
public PostDataAsyncTask(String textEmail, String hello) {
data = textEmail;
data1= hello;
}
long date = System.currentTimeMillis();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM MM dd, yyyy h:mm a");
String dateString = simpleDateFormat.format(Long.valueOf(date));
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
try {
postText();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String lenghtOfFile) {
}
private void postText(){
try{
String postReceiverUrl = "http://techcube.pk/game/game.php";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(postReceiverUrl);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("email", data));
nameValuePairs.add(new BasicNameValuePair("score", data1));
nameValuePairs.add(new BasicNameValuePair("datetime", dateString));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
String responseStr = EntityUtils.toString(resEntity).trim();
Log.v("SuccesS", "Response: " + responseStr);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now what i want is that i want to get the value of responseStr in my MainActivity that is generated when posttext method called.
How to show this responseStr value in the MainActivity?
Remember there is a new class that i made named as PostDataAsyncTask so how to access responseStr from this class and show it in my mainActivity as a Toast or Textview?
Please Help
You can create an interface that you pass into the method in question. For example
public interface INetworkResponse {
void onResponse(String response);
void onError(Exception e);
}
You would then need to create a concrete implementation of the interface. perhaps as a child class inside the activity that calls the AsyncTask.
public class MyActivity extends Activity {
private void Request() {
NetworkResponse response = new NetworkResponse();
new PostDataAsyncTask(textEmail, tValue, response).execute();
}
public class NetworkResponse implements INetworkResponse {
public void onResponse(String response) {
// here is where you would process the response.
}
public void onError(Exception e) {
}
}
}
Then change the async task constructor to include the new interface.
public class PostDataAsyncTask extends AsyncTask<String, String, String> {
GameActivity game= new GameActivity();
private String data,data1;
private INetworkResponse myResponse;
public PostDataAsyncTask(String textEmail, String hello, INetworkResponse response) {
data = textEmail;
data1 = hello;
myResponse = response
}
private void postText() {
// do some work
myResponse.onResponse(myResultString);
}
}
You can create a Handler as an Inner class inside your Activity to send data between your thread and UIthread:
public class YourHandler extends Handler {
public YourHandler() {
super();
}
public synchronized void handleMessage(Message msg) {
String data = (String)msg.obj;
//Manage the data
}
}
Pass this object in the header of PostDataAsyncTask
public PostDataAsyncTask(String textEmail, String hello, YourHandler mYourHandler) {
data = textEmail;
data1= hello;
this.mYourHandler = mYourHandler;
}
and send the data in postText() to the Activity:
if (resEntity != null) {
String responseStr = EntityUtils.toString(resEntity).trim();
msg = Message.obtain();
msg.obj = responseStr;
mYourHandler.sendMessage(msg);
Log.v("SuccesS", "Response: " + responseStr);
}
I am fetching data from server using AsynkTask which works fine but I want to use handler in AsynkTask to reduce load from main Thread.How can I use Handler in AsynkTask. Kindly help me to solve this problem.
Here is my code.
public class CLoginScreen extends Fragment {
public static String s_szLoginUrl = "http://192.168.0.999:8080/rest/json/metallica/getLoginInJSON";
public static String s_szresult = " ";
public static String s_szMobileNumber, s_szPassword;
public static String s_szResponseMobile, s_szResponsePassword;
public View m_Main;
public EditText m_InputMobile, m_InputPassword;
public AppCompatButton m_LoginBtn, m_ChangePass, m_RegisterBtn;
public CJsonsResponse m_oJsonsResponse;
public boolean isFirstLogin;
public JSONObject m_oResponseobject;
public LinearLayout m_MainLayout;
public CLoginSessionManagement m_oLoginSession;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
m_Main = inflater.inflate(R.layout.login_screen, container, false);
((AppCompatActivity) getActivity()).getSupportActionBar().hide();
m_oLoginSession = new CLoginSessionManagement(getActivity());
init();
return m_Main;
}
public void init() {
m_MainLayout = (LinearLayout) m_Main.findViewById(R.id.mainLayout);
m_InputMobile = (EditText) m_Main.findViewById(R.id.input_mobile);
m_InputPassword = (EditText) m_Main.findViewById(R.id.input_password);
m_LoginBtn = (AppCompatButton) m_Main.findViewById(R.id.btn_Login);
m_ChangePass = (AppCompatButton) m_Main.findViewById(R.id.btn_ChangePass);
m_ChangePass.setBackgroundColor(Color.TRANSPARENT);
m_ChangePass.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, new CChangePasswordScreen()).commit();
}
});
m_RegisterBtn = (AppCompatButton) m_Main.findViewById(R.id.btn_Register);
m_RegisterBtn.setBackgroundColor(Color.TRANSPARENT);
m_RegisterBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, new CRegistrationScreen()).commit();
}
});
m_LoginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new LoginAttempt().execute();
}
});
}
private class LoginAttempt extends AsyncTask<String, Void, String> {
public Dialog m_Dialog;
public ProgressBar m_ProgressBar;
#Override
protected void onPreExecute() {
super.onPreExecute();
m_Dialog = new Dialog(getActivity());
m_Dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
m_Dialog.setContentView(R.layout.progress_bar);
showProgress("Please wait while Logging...");// showing progress ..........
}
#Override
protected String doInBackground(String... params) {
getLoginDetails();// getting login details from editText...........
InputStream inputStream = null;
m_oJsonsResponse = new CJsonsResponse();
isFirstLogin = true;
try {
// 1. create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 2. make POST request to the given URL
HttpPost httpPost = new HttpPost(s_szLoginUrl);
String json = "";
// 3. build jsonObject
JSONObject jsonObject = new JSONObject();
jsonObject.put("agentCode", s_szMobileNumber);
jsonObject.put("pin", s_szPassword);
jsonObject.put("firstloginflag", m_oLoginSession.isLogin());
// 4. convert JSONObject to JSON to String
json = jsonObject.toString();
// 5. set json to StringEntity
StringEntity se = new StringEntity(json);
// 6. set httpPost Entity
httpPost.setEntity(se);
// 7. Set some headers to inform server about the type of the content
// httpPost.setHeader("Accept", "application/json"); ///not required
httpPost.setHeader("Content-type", "application/json");
// 8. Execute POST request to the given URL
HttpResponse httpResponse = httpclient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
// 9. receive response as inputStream
inputStream = entity.getContent();
System.out.print("InputStream...." + inputStream.toString());
System.out.print("Response...." + httpResponse.toString());
StatusLine statusLine = httpResponse.getStatusLine();
System.out.print("statusLine......" + statusLine.toString());
////Log.d("resp_body", resp_body.toString());
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
// 10. convert inputstream to string
if (inputStream != null) {
s_szresult = m_oJsonsResponse.convertInputStreamToString(inputStream);
//String resp_body =
EntityUtils.toString(httpResponse.getEntity());
}
} else
s_szresult = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
System.out.println("s_szResult....." + s_szresult);
System.out.println("password......" + s_szPassword);
// 11. return s_szResult
return s_szresult;
}
#Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
hideProgress();// hide progressbar after getting response from server......
try {
m_oResponseobject = new JSONObject(response);// getting response from server
new Thread() {// making child thread...
public void run() {
Looper.prepare();
try {
getResponse();// getting response from server
Looper.loop();
} catch (JSONException e) {
e.printStackTrace();
}
}
}.start();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void getResponse() throws JSONException {
if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Transaction Successful")) {
m_oLoginSession.setLoginData(s_szResponseMobile, s_szResponsePassword);
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, new CDealMainListing()).commit();
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Agentcode Can Not Be Empty")) {
showToast("Please Enter Valid Mobile Number");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Pin Can Not Be Empty")) {
showToast("Please Enter Password");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Invalid PIN")) {
showToast("Invalid Password");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Blocked due to Wrong Attempts")) {
showToast("You are blocked as You finished you all attempt");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Connection Not Available")) {
showToast("Connection Lost ! Please Try Again");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Not Found")) {
showToast("User not found ! Kindly Regiter before Login");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("OTP not verify")) {
showToast("Otp not Verify ! Kindly Generate Otp on Sign Up");
}
}
public void showToast(String message) {// method foe showing taost message
Toast toast = Toast.makeText(getActivity(), "" + message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
public void getLoginDetails() {
s_szMobileNumber = m_InputMobile.getText().toString();
s_szPassword = m_InputPassword.getText().toString();
}
public void showProgress(String message) {
m_ProgressBar = (ProgressBar) m_Dialog.findViewById(R.id.progress_bar);
TextView progressText = (TextView) m_Dialog.findViewById(R.id.progress_text);
progressText.setText("" + message);
progressText.setVisibility(View.VISIBLE);
m_ProgressBar.setVisibility(View.VISIBLE);
m_ProgressBar.setIndeterminate(true);
m_Dialog.setCancelable(false);
m_Dialog.setCanceledOnTouchOutside(false);
m_Dialog.show();
}
public void hideProgress() {
m_Dialog.dismiss();
}
}
}
As per android docs here
An asynchronous task is defined by a computation that runs on a
background thread and whose result is published on the UI thread.
And loading data from URL with Handler is not a good thing. Instead use Executor or ThreadPoolExecutor to do heavy background tasks.
You Can Use
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
getResponse();
}
});
you can do like this:
class MyAsyncTask extends AsyncTask<Object,Object,Object>{
Private Context c;
private Handler handler;
private final static int YOUR_WORK_ID = 0x11;
public MyAsyncTask(Context c,Handler handler){
this.c = c;
this.handler = handler;
}
protected Object doInBackground(Object... params){
//do your work
...
Message m = handler.obtainMessage();
m.what = YOUR_WORK_ID;
...
handler.sendMessage().sendToTarget();
}
}
And in your fragment ,you can init a handler as params to MyAsyncTask,and deal with you work in handleMessage();
I have web services and I want to create a class that should takes an email and password from server after authentication in hash table, and then saves email and password in shared preferences.
Try this class to call webservice in your app, i am sharing get and post both methods you can use any one as per your need.
public class CallService {
String url;
HttpEntity str1;
String str;
Context context;
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public CallService(String url1) {
this.url = url1;
}
public String getResponceWithPost() {
try {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters,5000000);
HttpConnectionParams.setSoTimeout(httpParameters,500000);
HttpConnectionParams.setTcpNoDelay(httpParameters,true);
HttpClient hc = new DefaultHttpClient(httpParameters);
HttpPost post= new HttpPost (url);
HttpResponse rp = hc.execute(post);
// //////////////
if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
str = EntityUtils.toString(rp.getEntity());
Log.e("Calling service", str);
return str;
}
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
public int getResponceWithGet() {
int code = 0;
try {
HttpClient hc = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse rp = hc.execute(get);
code= rp.getStatusLine().getStatusCode();
return code;
} catch (IOException e) {
Log.e("calling service", e.toString());
e.printStackTrace();
}
catch(Exception e)
{
Log.e("calling service", e.toString());
}
return code;
}}
this will return response from server like email password or other details.
and you can save these details in sharedpreference .
for shared preference follow this -
http://developer.android.com/guide/topics/data/data-storage.html#pref
and in your activity call your url using my call service class like this-
declare your hashTable in activity like this
Hashtable hashtable = new Hashtable();
call this method
new checkForLogin().execute();
and your async class
class checkForLogin extends AsyncTask<Void, Void,String>
{
#Override
protected void onPreExecute() {
progress= ProgressDialog.show(LoginScreen.this,"Authenticating !","Please Wait");
}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
Parse your json data here that will be in data
CallService cl2=new CallService("your server url here");
Log.e("login url is",""+Urls.loginurl);
data=cl2.getResponceWithPost();
Log.e("server response data","data = "+data);
hashtable.put(“email″, data.getString("email"));
hashtable.put(“pass″, data.getString("pass"));
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
progress.dismiss();
}
i hope this ll help you.
I'm developing an Android app. I want to post to a server using asynctask. However, I still have an error which indicates that the UI thread is blocked.
I want to parse the XML response and display it in a list view, but I cannot proceed because the UI thread is still blocked.
public class AsynchronousPost extends ListActivity implements OnClickListener {
EditText SearchValue;
Button SearchBtn;
String URL = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_interface);
SearchBtn = (Button) findViewById(R.id.searchbtn);
SearchBtn.setOnClickListener(this);
}
public void onClick(View views) {
new MyAsyncTask().execute();
}
private class MyAsyncTask extends AsyncTask<String, Integer, Document> {
private final String URL = "url";
private final String username = "username";
private final String password = "password";
private EditText SearchValue;
#Override
protected Document doInBackground(String... arg0) {
// TODO Auto-generated method stub
getXmlFromUrl(URL); // getting XML
return null;
}
#Override
protected void onPostExecute() {
//want to parse xml response
//display on listview
}
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
SearchValue = (EditText) findViewById(R.id.search_item);
String Schvalue = SearchValue.getText().toString();
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
5);
nameValuePairs
.add(new BasicNameValuePair("username", username));
nameValuePairs
.add(new BasicNameValuePair("password", password));
nameValuePairs.add(new BasicNameValuePair("searchItem",
Schvalue));
// response stored in response var
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
} catch (ClientProtocolException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
// return XML
return xml;
}
}
}
There are a couple problems that I see. First, you aren't passing anything in execute() but in your class declaration you are telling doInBackground() to expect a String. Secondly, you are telling onPostExecute() to expect a Document but you are returning null from doInBackground() and not taking any parameters in onPostExecute(). Unless I missed something, I don't see how this even compiles
protected Object doInBackground(String... params) {
//this method of AsyncTask is not running on the UI Thread -- here do just non UI taks
return result;
}
#Override
protected void onPostExecute(Object result) {
//I'm not sure but I think this method is running on the UI Thread
//If you have long operations here to do you will block UI Thread
//put the tasks in the doInBackground...
//to fill the elements in the UI elements use
//
runOnUiThread (new Runnable() {
#Override
public void run() {
//here fill your UI elements
}});
}
I have one database file whose name is menu.db and this file is located at server now i want to read data from this database.
i also have registration page on the application i am working on, as user press submit button then all the user information should be store on that database at server.
if anyone solved this problem then please help me.
if any one knows then please help me.
I have the following code. It authenticates the user password. you should call this method inside doBackground() of AsyncTask extended Class.
public boolean authenticate(String strUsername, String strPassword)
{
boolean bReturn = false;
InputStream pInputStream = null;
ArrayList<NameValuePair> pNameValuePairs = new ArrayList<NameValuePair>();
pNameValuePairs.add(new BasicNameValuePair("userid", strUsername));
pNameValuePairs.add(new BasicNameValuePair("password", strPassword));
try
{
HttpClient pHttpClient = new DefaultHttpClient();
String strURL = p_strServerIP + "Login.php";
HttpPost pHttpPost = new HttpPost(strURL);
pHttpPost.setEntity(new UrlEncodedFormEntity(pNameValuePairs));
HttpResponse pHttpResponse = pHttpClient.execute(pHttpPost);
HttpEntity pHttpEntity = pHttpResponse.getEntity();
pInputStream = pHttpEntity.getContent();
BufferedReader pBufferedReader = new BufferedReader(new InputStreamReader(pInputStream,"iso-8859-1"),8);
StringBuilder pStringBuilder = new StringBuilder();
String strLine = pBufferedReader.readLine();
pInputStream.close();
if(strLine != null)
{
if((strLine).equals("permit"))
{
bReturn = true;
}
}
}
catch (Exception e)
{
Log.e("log_tag", "Caught Exception # authenticate(String strUsername, String strPassword):" + e.toString());
}
return bReturn;
}
The class you extend from AsyncTask should be something like
class ConnectionTask extends AsyncTask<String, Void, Boolean>
{
private SharedPreferences mSettings;
private Context mContext;
ConnectionTask(SharedPreferences settings, Context context)
{
mSettings = settings;
mContext = context;
}
protected void onProgressUpdate(Integer... progress)
{
}
protected void onPostExecute(Boolean result)
{
Toast.makeText(mContext, "Authentication over.", Toast.LENGTH_LONG).show();
}
#Override
protected Boolean doInBackground(String... params)
{
pVerifier.authenticate(params[0], params[1]);
return true;
}
}