I added Yahoo weather library to m project. Then I tried to implement YahooWeatherInfoListener to the main fragment.
There is a problem.
Inside AsyncTask I can't cast YahooWeatherInfoListener to the fragment.
I think there is sth I'm doin wrong inside AsncTask. Please take a look:
import zh.wang.android.apis.yweathergetter4a.WeatherInfo;
import zh.wang.android.apis.yweathergetter4a.YahooWeather;
import zh.wang.android.apis.yweathergetter4a.YahooWeather.SEARCH_MODE;
import zh.wang.android.apis.yweathergetter4a.YahooWeatherInfoListener;
import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class HomeFragment extends Fragment implements YahooWeatherInfoListener {
public HomeFragment(){}
private TextView Temperature;
private YahooWeather mYahooWeather = YahooWeather.getInstance(5000, 5000, true);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
Temperature = (TextView) rootView.findViewById(R.id.txtLabel);
new searchByGPS().execute();
return rootView;
}
private class searchByGPS extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... unused) {
mYahooWeather.setNeedDownloadIcons(true);
mYahooWeather.setSearchMode(SEARCH_MODE.GPS);
mYahooWeather.queryYahooWeatherByGPS(getActivity().getApplicationContext(), (YahooWeatherInfoListener) this);
return null;
}
protected void onPostExecute(Void unused) {
}
}
#Override
public void gotWeatherInfo(WeatherInfo weatherInfo) {
// TODO Auto-generated method stub
Temperature.setText(weatherInfo.getCurrentTempC());
}
}
That's because in
(YahooWeatherInfoListener) this
this refers to the AsyncTask. Instead, you need to use:
(YahooWeatherInfoListener) HomeFragment.this
The cleaner way to implement this would be:
private class SearchByGPSTask extends AsyncTask<Void, Void, Void>{
private YahooWeatherInfoListener mListener;
public SearchByGPSTask( YahooWeatherInfoListener listener ) {
super();
mListener = listener;
}
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... unused) {
mYahooWeather.setNeedDownloadIcons(true);
mYahooWeather.setSearchMode(SEARCH_MODE.GPS);
mYahooWeather.queryYahooWeatherByGPS(getActivity().getApplicationContext(), mListener );
return null;
}
protected void onPostExecute(Void unused) {
}
}
(note: Classes are generally uppercase, and better nouns -- "searchByGPS" sounds like a method, while "SearchByGPSTask" indicates that it's a class meant to do something.)
protected Void doInBackground(Void... unused) {
mYahooWeather.setNeedDownloadIcons(true);
mYahooWeather.setSearchMode(SEARCH_MODE.GPS);
mYahooWeather.queryYahooWeatherByGPS(getActivity().getApplicationContext(), (YahooWeatherInfoListener) HomeFragment.this);
return null;
}
You have to change your this to HomeFragment.this because this is directly connected to your AsyncTask.
With this line mYahooWeather.queryYahooWeatherByGPS(getActivity().getApplicationContext(), (YahooWeatherInfoListener) this);, you are trying to cast the AsyncTask to a YahooWeatherInfoListener. Use HomeFragment.this instead
Related
I want to show a toast message but getContext() in Toast.makeText((getContext()," Message" , Toat.LENGTH_LONG.show())) is giving error
Cannot resolve Method.
The problem is that in which class I want to show the Toast message is not MainActivity class. This is AsyncTask class. Can i show Toast message in other classes (other than MainActivity class) as the above mentioned problem?
import android.os.AsyncTask;
import android.widget.Toast;
public class myClass extends AsyncTask<String, String, String> {
public myClass(double a, double b,Context context ) {
this.a = a;
this.b=b;
this.context = context;
}
protected String doInBackground(String... params) {
return null;
}
protected void onPostExecute(String result) {
Toast.makeText((getApplicationContext(), "Message", Toast.LENGTH_LONG).show();
}
}
Edit
I made the constructor (See above code) but in the MainActivity class I am calling in this way myClassObj = new myClass(a, b,this); but is giving error
myClas() in myClass cannot be applied to:
Expected Actual
Parameters Arguments
a: double a
b: double b
context: android.content.Context this(anonymous...view.View.OnClickListener)
Edit3
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
myClass Object;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
double age = 16;
double number = 33;
Object = new myClass(age,number,this);
}
});
}
}
SecondClass.
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
public class myClass extends AsyncTask<String, String, String> {
Context context;
double a;
double b;
public myClass(double a, double b,Context context ) {
this.a = a;
this.b=b;
this.context = context;
}
protected String doInBackground(String... params) {
return null;
}
protected void onPostExecute(String result) {
Toast.makeText((context), "Message", Toast.LENGTH_LONG).show();
}
}
When you are using this it refers to the enclosing class. In your case this is View.OnClickListener. But you need to pass the context of your Activity.
So you need to call it this way,
Object = new myClass(age,number, MainActivity.this);
You can use the ApplicationClass.getinstance().getApplicationContext();
Edit 3
Do this in your MainActivity:
Object = new myClass(age,number,MainActivity.this);
And do this in your myClass
Toast.makeText(context, "Message", Toast.LENGTH_LONG).show();
Edit 2
class MyClass extends AsyncTask<Void, Void, Void> {
int SPLASH_SHOW_TIME=3000;
Context context;
public MyClass(Context context ) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
try {
Thread.sleep(SPLASH_SHOW_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Toast.makeText(context, "Created a server socket",Toast.LENGTH_LONG).show();
}
}
I have four classes:
MainActivity extends AppCompactActivity
MainAsyncTask extends AsyncTask<String, String, List>
Intermediate extends MainAsyncTask and have two functions. (FuncA, FuncB)
Leaf extends Intermediate and implementation of doInBackground() and onPostExecute().
When I run the application it prompts:
Unable to instantiate activity ComponentInfo{}: android.os.NetworkonMainThreadException.
How can I get rid off the Error. As far as My understanding is concerned, doInBackground() and onPostExecute()should be implemented in MainAsyncTask class?
Classes are :
MianActivity.java
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Leaf object = new Leaf();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button fab = (Button) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
object.execute();
}
});
}
}
MainAsyncTask.java
import android.os.AsyncTask;
public class MainAsync extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(String... text) {
}
}
Intermediate.java
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
public class Intermediate extends MainAsync{
public Document FunA(){
System.out.println("Printed FunA()");
String url = "http://blogs.tribune.com.pk/story/37034/zakir-naik-has-a-large-following-in-pakistan-should-we-be-alarmed/";
Document doc = null;
try {
doc = Jsoup.connect(url).timeout(10 * 1000).get();
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
public void FunB(){ System.out.println("Printed FunB()");}
}
}
Leaf.java
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Leaf extends Intermediate{
Document HTM = FunA();
public void FunC() {
String heading = "";
System.out.println("Printed FunC()");
Elements seep = HTM.select("h1");
for (Element foo : seep) {
heading = foo.text();
System.out.println(heading);
break;
}
}
public void FunD() {
System.out.println("Printed FunD()");
}
public void FunE() {
System.out.println("Printed FunE()");
}
#Override
protected String doInBackground(String... params) {
FunB();FunC();FunD();FunE();
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(String... text) {
}
}
The purpose of doing in this way is to add FuncA and FuncB along with AsyncTask methods in one class that is Leaf class.
In the absence of a stack trace I would say:
Initiating your Leaf class causes the HTM variable to be initiated.
The HTM variable is initiated by calling the FunA method.
The FunA method runs network accessing code and is not running inside DoInBackground (and therefore running on the main thread).
Your network code can only be run inside DoInBackground if you wish to not get a NetworkOnMainThread Exception.
The exception is thrown before you even start the AsyncTask as just the act of creating it causes the FunA code to run.
Move this line inside DoInBackground so it runs when the AsyncTask is executed and not when it is created.
Document HTM = FunA();
On a separate note, your class hierarchy is very convoluted. You do not need Intermediate or Leaf classes. All that code could be easily moved to the MainAsync class and so would be much easier to understand.
Hi friends I know there is a bunch of questions about this topic but I can not get any result from them. i am parsing xml data with my ClassIsInternalParser extends default handler. I use this class in my activity in an inner class PostAsync extends AsyncTask
but the reason is i can not return the data that ı collected in PostAsync class to main activity. it sets only null
here is my codes
package com.example.uiexercisesplash;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ClassIsInternalListViewActivity extends Activity implements OnClickListener{
TextView tv, tv2;
Button back;
String[][] array = new String[10][3];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.classisinternal_listview);
new PostAsync().execute();
tv=(TextView) findViewById(R.id.tatar);
tv2= (TextView) findViewById(R.id.tatar2);
tv2.setText(array[0][0]); //Why this sets null!!
back= (Button) findViewById(R.id.back);
back.setOnClickListener(this);
}
class PostAsync extends AsyncTask<Void, Void,String[][]>{
ProgressDialog pd;
ClassIsInternalParser parser;
#Override
protected void onPreExecute() {
//we can set up variables here
pd = ProgressDialog.show(ClassIsInternalListViewActivity.this,
"Classisinternal","Loading last post...",true,false);
}
protected void onPostExecute(String[][] result) {
//in this way it sets correctly
tv.setText(result[0][0]);
array=result;
pd.dismiss();
pd.cancel();
}
protected String[][] doInBackground(Void... params) {
parser = new ClassIsInternalParser();
parser.get();
return parser.dataArray;
}
}
#Override
public void onClick(View v) {
finish();
}
}
Try to create PostAsync object and call execute() from that object. After that call get() method to retrieve your return array like this:
PostAsync obj=new PostAsync(this);
obj.execute();
String[][] array=obj.get();
tv2.setText(array[0][0]);
tv2.setText(array[0][0]); is null because you are getting array value before setting values in it,i.e. tv2.setText(array[0][0]); is execute before completing Asynctask.
So do this step in onPostExecute method as
protected void onPostExecute(String[][] result) {
//in this way it sets correctly
tv.setText(result[0][0]);
tv2.setText(result[0][2]);
array=result;
tv2.setText(array[0][0]);// add here
pd.dismiss();
pd.cancel();
}
I start in Application class, in onCreate, a background thread (AsyncTask) which does some time consuming job (between 15 - 70 seconds).
In an activity I need to make some operations only if that task started in Application onCreate() method is completed.
My solution for this is:
Application class
create an interface with a single method
in AsyncTask onPostExecute method I update the listener
I have also a boolean variable to know from poutside if asyncTask is in progress or is terminated
MyActivity class
I implement the listener
when pressing the button:
if asyncTask is in progress I set the listener and I will be informed in onCommandEnded when AsyncTask is done and do there the operations
if asyncTask job is done I do here the following operations.
I'm not sure if this is the correct way to do it...
import android.app.Application;
import android.content.Context;
import android.os.AsyncTask;
public class MyApplicationClass extends Application {
protected static MyApplicationClass instance;
public static MyApplicationClass getInstance() {
return instance;
}
private ApplicationListener listener;
public void setListener(ApplicationListener listener) {
this.listener = listener;
}
public static interface ApplicationListener {
void onCommandEnded();
}
private boolean isInProgress;
#Override
public void onCreate() {
super.onCreate();
instance = this;
CommandAsyncTask copyFfmpeg = new CommandAsyncTask();
copyFfmpeg.execute();
}
private class CommandAsyncTask extends AsyncTask<Void, Void, Double> {
#Override
protected void onPreExecute() {
super.onPreExecute();
isInProgress = true;
}
#Override
protected Double doInBackground(Void... params) {
//do some time consuming operations here
return null;
}
#Override
protected void onPostExecute(Double aDouble) {
if (listener != null) {
listener.onCommandEnded();
}
isInProgress = false;
super.onPostExecute(aDouble);
}
}
public boolean isInProgress() {
return isInProgress;
}
}
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MyActivity extends Activity implements MyApplicationClass.ApplicationListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (MyApplicationClass.getInstance().isInProgress()) {
MyApplicationClass.getInstance().setListener(MyActivity.this);
} else {
//start new asynctask
}
}
});
}
#Override
public void onCommandEnded() {
//start here new asynctask
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MyActivity"
/>
</LinearLayout>
I am using ListFragment but i need to use Fragment to display the listview. How do i use Fragment instead of ListFragment plz help me. Also give me some explanation which one is better to use.
i want to use extends Fragment instead * extends ListFragment*
import java.util.ArrayList;
import android.app.Activity;
import android.app.ListFragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
public class CountryListFragment extends ListFragment{
ArrayList<Video> videos;
Activity mactivity;
/** List of countries to be displayed in the ListFragment */
ListFragmentItemClickListener ifaceItemClickListener;
/** An interface for defining the callback method */
public interface ListFragmentItemClickListener {
/** This method will be invoked when an item in the ListFragment is clicked */
void onListFragmentItemClick(int position);
}
/** A callback function, executed when this fragment is attached to an activity */
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mactivity=activity;
try{
/** This statement ensures that the hosting activity implements ListFragmentItemClickListener */
ifaceItemClickListener = (ListFragmentItemClickListener) activity;
}catch(Exception e){
Toast.makeText(activity.getBaseContext(), "Exception",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new SubTask().execute();
}
private class SubTask extends AsyncTask<Void, Void, ArrayList<Video>>{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected ArrayList<Video> doInBackground(Void... params) {
//Crearte instance to http call
GetHttpCall getCall=new GetHttpCall();
String response=null;
try {
response=getCall.connect();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JSONParser _parser=new JSONParser();
_parser.parseHttpJson(response);
String [] item = JSONParser.num_title;
int []id=JSONParser.num_id;
videos=new ArrayList<Video>();
for(int i=0;i<item.length;i++)
{
Video vid=new Video();
vid.setTitle(item[i]);
vid.setId(id[i]);
videos.add(vid);
}
return videos;
}
#Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(ArrayList<Video> result) {
super.onPostExecute(result);
BindDataAdapter adapter = new BindDataAdapter(mactivity, videos);
setListAdapter(adapter);
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
/** Invokes the implementation of the method onListFragmentItemClick in the hosting activity */
ifaceItemClickListener.onListFragmentItemClick(position);
}
}
check out this
clone it, create project in your IDE and look at the sample app 'TestBedDSLV' and how it uses 'DSLVFragment' and ListFragment.