This is the code i am working on. Here I cant update the UI until myOnResponse is finished.Because we are doing a doInBackgrnd, so my textresponse is empty. And Since onPostExecute is happening right after.
For his I think PublicProgres should help.
How to Call PublishProgress at AsyncTask ?
private class ConversationTask extends AsyncTask<String, Void, String> {
String textResponse = new String();
#Override
protected String doInBackground(String... params) {
System.out.println("in doInBackground");
MessageRequest newMessage = new MessageRequest.Builder().inputText(params[0]).context(context).build();
// async
GLS_service.message("xxxxxxxxx", newMessage).enqueue(new ServiceCallback<MessageResponse>() {
#Override
public void onResponse(MessageResponse response) {
context = response.getContext();
textResponse = response.getText().get(0);
action5(textResponse);
System.out.println(textResponse);
}
#Override
public void onFailure(Exception e) {
}
});
return textResponse;
}#Override protected void onPostExecute(String result) {
reply.setText(textResponse);
}
}
Please help.
I don't think that you have to use AsyncTask.
You can do something like this :
YourTask.java
public class YourTask implements Runnable {
private Handler handler;
private TextView textView;
public YourTask(TextView textView){
this.textView = textView;
handler = new Handler();
}
#Override
public void run() {
MessageRequest newMessage = new MessageRequest.Builder().inputText(params[0]).context(context).build();
GLS_service.message("xxxxxxxxx", newMessage).enqueue(new ServiceCallback<MessageResponse>() {
#Override
public void onResponse(MessageResponse response) {
final String textResponse = response.getText().get(0);
handler.post(new Runnable() {
#Override
public void run() {
if(textView != null){
textView.setText(textResponse);
}
}
});
}
#Override
public void onFailure(Exception e) {
}
});
}
}
And now how to use it :
SomeActivity.java
...
textView = (TextView) findViewById(R.id.textView);
...
Thread thread = new Thread(new YourTask(textView));
thread.start();
...
Nevertheless if you want to do this action in Asynktask just try this
private class ConversationTask extends AsyncTask<String, Void, Void> {
private Handler handler;
public ConversationTask(){
handler = new Handler();
}
#Override
protected Void doInBackground(String... params) {
MessageRequest newMessage = new MessageRequest.Builder().inputText(params[0]).context(context).build();
GLS_service.message("xxxxxxxxx", newMessage).enqueue(new ServiceCallback<MessageResponse>() {
#Override
public void onResponse(MessageResponse response) {
final String textResponse = response.getText().get(0);
handler.post(new Runnable() {
#Override
public void run() {
if(reply != null){
reply.setText(textResponse);
}
}
});
}
#Override
public void onFailure(Exception e) {
}
});
return null;
}
}
Hope it helps
Related
I'm not experienced in Java development and migrating from Eclipse. I don't know how to use the nested classes in my case where I need to extend AppCompactActivity and IOIOActivity. Considering, I have another inner class Looper already extending another class. The code below isn't running what is inside Testing class. Can someone help me about how to execute my inner class, which is Testing class.
My code:
public class MainActivity extends AppCompatActivity {
private class Testing extends IOIOActivity {
private ToggleButton button_;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_ = (ToggleButton) findViewById(R.id.toggleButton);
}
class Looper extends BaseIOIOLooper {
/** The on-board LED. */
private DigitalOutput led_;
#Override
protected void setup() throws ConnectionLostException {
showVersions(ioio_, "IOIO connected!");
led_ = ioio_.openDigitalOutput(0, true);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
led_.write(!button_.isChecked());
Thread.sleep(100);
}
#Override
public void disconnected() {
enableUi(false);
toast("IOIO disconnected");
}
#Override
public void incompatible() {
showVersions(ioio_, "Incompatible firmware version!");
}
}
#Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
private void showVersions(IOIO ioio, String title) {
toast(String.format("%s\n" +
"IOIOLib: %s\n" +
"Application firmware: %s\n" +
"Bootloader firmware: %s\n" +
"Hardware: %s",
title,
ioio.getImplVersion(IOIO.VersionType.IOIOLIB_VER),
ioio.getImplVersion(IOIO.VersionType.APP_FIRMWARE_VER),
ioio.getImplVersion(IOIO.VersionType.BOOTLOADER_VER),
ioio.getImplVersion(IOIO.VersionType.HARDWARE_VER)));
}
private void toast(final String message) {
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
private int numConnected_ = 0;
private void enableUi(final boolean enable) {
// This is slightly trickier than expected to support a multi-IOIO use-case.
runOnUiThread(new Runnable() {
#Override
public void run() {
if (enable) {
if (numConnected_++ == 0) {
button_.setEnabled(true);
}
} else {
if (--numConnected_ == 0) {
button_.setEnabled(false);
}
}
}
});
}
}
}
Thankss
I found my answer and I would like to share it with you all for the future. This is for starting a new IOIOActivity in Android Studio. IOIO developers haven't written the official IOIO code for AppCompactActivity yet. After couple of days trying, its finally tested and working with IOIO led.
Create a new Class file called AppCompactIOIOActivity (I just like that name) in your package. Note: all credits to Ytai. IOIO code from App507
public class AppCompactIOIOActivity extends AppCompatActivity implements IOIOLooperProvider {
private final IOIOAndroidApplicationHelper helper_ = new IOIOAndroidApplicationHelper(this, this);
public AppCompactIOIOActivity() {
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.helper_.create();
}
protected void onDestroy() {
this.helper_.destroy();
super.onDestroy();
}
protected void onStart() {
super.onStart();
this.helper_.start();
}
protected void onStop() {
this.helper_.stop();
super.onStop();
}
#SuppressLint("WrongConstant")
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if((intent.getFlags() & 268435456) != 0) {
this.helper_.restart();
}
}
protected IOIOLooper createIOIOLooper() {
throw new RuntimeException("Client must override one of the createIOIOLooper overloads!");
}
public IOIOLooper createIOIOLooper(String connectionType, Object extra) {
return this.createIOIOLooper();
}
}
Then in your MainActivity
public class MainActivity extends AppCompactIOIOActivity {
private ToggleButton button_;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_ = (ToggleButton) findViewById(R.id.toggleButton);
}
class Looper extends BaseIOIOLooper {
/** The on-board LED. */
private DigitalOutput led_;
#Override
protected void setup() throws ConnectionLostException {
showVersions(ioio_, "IOIO connected!");
led_ = ioio_.openDigitalOutput(0, true);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
led_.write(!button_.isChecked());
Thread.sleep(100);
}
#Override
public void disconnected() {
enableUi(false);
toast("IOIO disconnected");
}
#Override
public void incompatible() {
showVersions(ioio_, "Incompatible firmware version!");
}
}
#Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
private void showVersions(IOIO ioio, String title) {
toast(String.format("%s\n" +
"IOIOLib: %s\n" +
"Application firmware: %s\n" +
"Bootloader firmware: %s\n" +
"Hardware: %s",
title,
ioio.getImplVersion(IOIO.VersionType.IOIOLIB_VER),
ioio.getImplVersion(IOIO.VersionType.APP_FIRMWARE_VER),
ioio.getImplVersion(IOIO.VersionType.BOOTLOADER_VER),
ioio.getImplVersion(IOIO.VersionType.HARDWARE_VER)));
}
private void toast(final String message) {
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
private int numConnected_ = 0;
private void enableUi(final boolean enable) {
// This is slightly trickier than expected to support a multi-IOIO use-case.
runOnUiThread(new Runnable() {
#Override
public void run() {
if (enable) {
if (numConnected_++ == 0) {
button_.setEnabled(true);
}
} else {
if (--numConnected_ == 0) {
button_.setEnabled(false);
}
}
}
});
}
}
Don't forget to add your resources and dependances from IOIO developers. Good luck!
I am trying to create an AsyncTask for following function:
private void updateStreamImageRequest() {
countDownTimer = new CountDownTimer(10000, 2000) {
#Override
public void onTick(long millisUntilFinished) {
imageRequest();
}
#Override
public void onFinish() {
countDownTimer.start();
}
};
}
I do not have much knowledge in AsyncTaskand I am struggling to make it work. The AsyncTask shall continueally run a get request.
So far I have done this so far but it does not work:
public void getImgAsync() {
new requestAsyncTask();
}
public class requestAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
countDownTimer = new CountDownTimer(10000, 2000) {
#Override
public void onTick(long millisUntilFinished) {
API_StreamImage_Request();
}
#Override
public void onFinish() {
countDownTimer.start();
}
};
return null;
}
}
So do it this way -
Create your Countdown timer that runs for 10 seconds. So it will finish after 10 seconds. Then in finish method call your Asynctask to fetch in background.
countDownTimer = new CountDownTimer(10000, 5000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
new requestAsyncTask().execute();
}
};
countDownTimer.start();
class requestAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
countDownTimer.cancel();
countDownTimer.start();
}
#Override
protected Void doInBackground(Void... params) {
API_StreamImage_Request();
return null;
}
}
You might have to create a global variable of your countdown timer so that you can access it inside your asynctask class. Or you can even pass it as well if you want.
You can also use a Handler for this.
private int mInterval = 10000;
private Handler mHandler = new Handler();
Runnable requestCaller = new Runnable() {
#Override
public void run() {
try {
new requestAsyncTask().execute();
} finally {
mHandler.postDelayed(requestCaller, mInterval);
}
}
};
Or a Timer
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
new requestAsyncTask().execute();
}
},0, 10000);
This question already has answers here:
how to return result from asyn call
(2 answers)
Closed 7 years ago.
Activity.java
//Activity stuff
MyClass mc = new MyClass();
mc.getText();
public void dosomething() {
textview.setText(mc.getText());
}
MyClass.java
class MyClass {
String text;
public void setText() {
class GetTextFromWEB extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String url = urls[0];
String output;
//Getting text from web
return output;
}
#Override
protected void onPostExecute(String _text) {
text = _text;
}
}
String url = "google.com";
//Doing with url something
new GetText().execute(url);
}
public String getText() {return text;}
}
Promblem is - in activity setText do faster, then AsyncTask do it's job.
So when setText run, it's run like setText(null)
I need to check in activity, is asynk ended, so i have my text to set.
I hope i explained it
And i don't even need exactly AsyncTask, i need jsoup working, so if there is solution with another thread-class, with which jsoup will work, i can use it
Edit
class GetLyrics extends AsyncTask<String, Void, String> { //Class for getting lyrics
private Context con;
public GetLyrics(Context con) {
this.con = con;
}
#Override
protected String doInBackground(String... urls) {
//do something
}
#Override
protected void onPostExecute(String _lyrics) {
lyrics = _lyrics;
con.runOnUiThread(new Runnable() {
#Override
public void run() {
((TextView) findViewById(R.id.lyricsOutput)).setText(lyrics);
}
});
}
}
Call the method setting your text in the postExecute inside your AsyncTask or set the text directly on your postExecute method.
And wrap the line with setText() inside runOnUIThread (otherwise you will get an exception saying that the view can be accessed only by the thread that created it, since you are setting the text from async task).
Setting the text would be something like this
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
((TextView) findViewById(R.id.txtFieldName)).setText("your text");
}
});
That way you can quit worrying about checking if the async task is finished. But avoid doing complex ui operations like this. Since this is just setting the text on TextView, it should be allright.
1: Make my first project from my previous post and add some new lines in it to get data from http: api's.
public class Example extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("parameter1", "xyz"));
params.add(new BasicNameValuePair("parameter2", "abc"));
params.add(new BasicNameValuePair("parameter3", "opqr"));
ServerConnection task = new ServerConnection(this, new ResultListener() {
#Override
public void result(String response) {
Toast.make(this, response, Toast.LENGTH_LONG).show();
}
#Override
public void loader(boolean visble) {
}
#Override
public void connectionLost(String error) {
Toast.make(this, error, Toast.LENGTH_LONG).show();
}
});
}
public class ServerConnection extends AsyncTask<String, String, String> implements Constant {
ResultListener listener;
private String Method = "GET";
private List<NameValuePair> params = new ArrayList<NameValuePair>();
private Context context;
private ConnectionDetector cd;
// public static Drawable drawable;
public ServerConnection(Context context, ResultListener r) {
this.context = context;
this.listener = r;
cd = new ConnectionDetector(context);
this.execute();
}
public boolean isConnection() {
return cd.isConnectingToInternet();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... arg0) {
if (!isConnection()) {
cancel(true);
return "Sorry!connection lost,try again or later";
}
ApiResponse air = new ApiResponse();
System.out.println("working hre" + "hi");
String json;
try {
json = air.makeHttpRequest(URL, getMethod(), getParams());
} catch (Exception e) {
json = e.getMessage();
cancel(true);
return json;
}
return json;
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
protected void onCancelled(String result) {
listener.connectionLost(result);
rl.connectionLost("Sorry!connection lost,try again or later");
super.onCancelled(result);
}
#Override
protected void onPostExecute(String result) {
System.out.println("onpost" + result);
listener.result(result);
listener.loader(true);
super.onPostExecute(result);
}
public String getMethod() {
return Method;
}
public void setMethod(String method) {
Method = method;
}
public List<NameValuePair> getParams() {
return params;
}
public void setParams(List<NameValuePair> params) {
this.params = params;
}
}
Example
I want create Socket connection but i have some problem. I must create it in new Thread but i can not.
public class SocketManager {
private static SocketManager instance;
private BufferedReader in;
private PrintWriter out;
private Socket mSocket = null;
public static SocketManager me() {
if (instance == null) {
instance = new SocketManager();
}
return instance;
}
public void connection() {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
mSocket = new Socket(Constants.CHAT_SERVER_URL, 4444);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
public boolean isConnected() {
return mSocket.isConnected();
}
and
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
status = (TextView) findViewById(R.id.status);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
SocketManager.me().connection();
if (SocketManager.me().isConnected()) {
status.setText("Connected");
} else {
status.setText("Disconnected");
}
I have error:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.net.Socket.isConnected()' on a null object reference
Becouse mSocket create in new Thread and when i call it it == null; How can create mSocket in new Thread and use it?
Best way is to use an interface.
Create an interface in your Socketmanager class
public class SocketManager {
private static SocketManager instance;
private SocketListner listner;
public interface SocketListner {
void onConnectionSuccess();
void onConnectionFailed();
}
public void connection(SocketListner listner) {
this.listner = listner;
new ConnectionTask().execute();
}
And return a boolean value from doInBackGround() method to check if the connection is success or not
class ConnectionTask new AsyncTask<Void, Void, Boolean>() {
#Override
protected Void doInBackground(Void... params) {
//...your code
}
#Override
protected void onPostExecute(Boolean result) {
if(result) {
listner.onConnectionSuccess();
} else {
listner.onConnectionFailed();
}
}
}
And in your activity implement the interface
public class YourActivity imlpements SocketListner {
#Override
protected void onCreate(Bundle savedInstanceState) {
//your code
..
}
#Override
void onConnectionSuccess() {
//your socket is connected
status.setText("Connected");
}
#Override
void onConnectionFailed() {
status.setText("Disconnected");
}
}
I think method "isConnected()" is trying to access mSocket before it is initialized.
Try to change it to:
public boolean isConnected() {
return mSocket == null ? false : mSocket.isConnected();
}
This will avoid the NullPointerException on this method.
But the correct approach here would be to use a callback so the child thread can inform the main thread when it has finished.
public class SocketTask extends AsyncTask<Void, Void, Void> {
public interface AsyncTaskListener<T> {
void onTaskCompleted(T t);
}
private final AsyncTaskListener<String> listener;
public SocketTask(AsyncTaskListener<String> listener) {
this.listener = listener;
}
#Override
protected Void doInBackground(Void... params) {
try {
mSocket = new Socket(Constants.CHAT_SERVER_URL, 4444);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute() {
listener.onTaskCompleted();
}
}
You class SocketManager need to implement the callback:
public class SocketManager implements SocketTask.AsyncTaskListener {
}
Add boolean to know your asynctask is complete or not.
boolean mIsSocketInstanceCreated = false;
public void connection() {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
mSocket = new Socket(Constants.CHAT_SERVER_URL, 4444);
mIsSocketInstanceCreated = true;
} catch (IOException e) {
e.printStackTrace();
mIsSocketInstanceCreated = false;
}
return null;
}
}.execute();
}
public boolean isConnected() {
if (mIsSocketInstanceCreated)
return mSocket.isConnected();
return false;
}
I want to show a circle progressdialog when some functions run in backstage. so I write such a series of code:
pd = ProgressDialog.show(GridLayoutActivity.this, "","...");
new Thread(new Runnable() {
public void run() {
someFunc();
handler.sendEmptyMessage(0);// 执行耗时的方法之后发送消给handler
}
}).start();
But the progressDialog doesn't roll? why?
Try with Asynchronous task, here i post the example code, you may change as per you own
public class BackGround_Task extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(
YourClassName.this);
// can use UI thread here
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.setCancelable(false);
this.dialog.show();
}
#Override
protected Void doInBackground(Void... params) {
//Your Background Task
return null;
}
protected void onPostExecute(Void result) {
//What will you do after the completion of Background process
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
Just use something like this:
ProgressDialog progressDialog = new ProgressDialog(GridLayoutActivity.this);
progressDialog.setMax(100);
progressDialog.setProgress(0);
progressDialog.setMessage("...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
new Thread(new Runnable() {
public void run() {
someFunc();
handler.sendEmptyMessage(0);// 执行耗时的方法之后发送消给handler
}
}).start();
Send handler message after try block. Use like this:
pd = ProgressDialog.show(SetFrames.this,"Loading", "Please Wait...",true);
new Thread() {
public void run() {
try {
//your function
}catch(Exception e)
{
}
handler.sendEmptyMessage(0);
pd.dismiss();
}
}.start();
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
}
};