I am trying to run the following code:
public class MyListActivity extends ListActivity {
private static class MyListLoadingCallback implements Handler.Callback {
private ListActivity activity;
private MyListManager myListManager;
public MyListLoadingCallback(ListActivity activity,
MyListManager articleListManager) {
this.activity = activity;
this.myListManager = myListManager;
}
#Override
public boolean handleMessage(Message message) {
throw new NotYetImplementedException();
}
}
private MyListManager myListManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myListManager.fetchArticles(new Handler(
new MyListLoadingCallback(this, MyListManager)));
}
I am getting a Null pointer at articleListManager.fetchArticles(new Handler(new MyListLoadingCallback(this, MyListManager)));
My other class looks like the following:
public class MyListManager {
public void fetchArticles(final Handler handler) {
}
}
Can someone please walk me / help me with this snippet of code for better understanding. I don't seem to fully understand it.
The error seems quite clear :).
There is only one "reference" being accessed in the line that's throwing the exception (myListManager.fetchArticles(new Handler(new MyListLoadingCallback(this, MyListManager)));) and it is myListManager, so it must be NULL. And looking at the code, you never initialize it to anything, so it is indeed NULL :)
Related
I am trying to run a AlertDialog in my flutter plugin. So I need the Activity context. I tried using the Application context. However, I was greeted with this fine error and learned that I must use the Activity context.
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
For some reason when I call getActivity() it always returns null. I was wondering if anyone could give me some pointers as to why this is happening. Here is my Plugin class I cleaned it up so it only contains the ActivityAware code. Did I not implement something correctly? Any help would be much appreciated!
public class MyPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
private ActivityPluginBinding activityBinding;
private FlutterPluginBinding flutterBinding;
#Override
public void onAttachedToEngine(#NonNull FlutterPluginBinding flutterPluginBinding) {
flutterBinding = flutterPluginBinding;
}
#Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
activityBinding = binding;
}
#Override
public void onDetachedFromActivity() {
activityBinding = null;
}
#Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
activityBinding = binding;
}
#Override
public void onDetachedFromActivityForConfigChanges() {
activityBinding = null;
}
// Implementation
public Context getApplicationContext() {
return (flutterBinding != null) ? flutterBinding.getApplicationContext() : null;
}
public Activity getActivity() {
return (activityBinding != null) ? activityBinding.getActivity() : null;
}
}
Those objects might have cleared by time they are accessed. You can keep WeakReference to Application context and Activity context and access them later. This way you will avoid memory leak as well.
Something like
private WeakReference<Context> weakApplicationContext;
private WeakReference<Activity> weakActivity;
and then
#Override
public void onAttachedToEngine(#NonNull FlutterPluginBinding flutterPluginBinding) {
weakApplicationContext = new WeakReference<>(flutterPluginBinding.getApplicationContext());
}
#Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
weakActivit = new WeakReference<>(binding.getActivity());
}
Then access them as
public Activity getActivity() {
return weakActivity.get();
}
I am doing some coding stuff with android. Nearly I faced a problem and to solve this I need an anonymous AsyncTask class to execute. But I also need to pass and object to this class before execution. I tried the below code but it's not working and I did not find any solution by googling also.
public void saveCartToRoom(CartsPay cartsPay){
new AsyncTask<Void,Void,Void>(){
CartsPay cartsPay;
#Override
protected Void doInBackground(Void... voids) {
return null;
}
public void setRQ(CartsPay cartsPay){
this.cartsPay= cartsPay;
}
}.setRQ(cartsPay).execute();
}
Here is how to pass a CartsPay parameter to an anonymousAsyncTask
new AsyncTask<CartsPay,Void,Void>(){
CartsPay cartsPay;
#Override
protected Void doInBackground(CartsPay... params) {
this.cartsPay = params[0];
// Your code ...
return null;
}
public AsyncTask setRQ(CartsPay cartsPay){
this.cartsPay= cartsPay;
return this;
}
}.execute(cartsPay);
You can just do it like that:
class CustomAsyncTask extends AsyncTask<Void, Void, Void> {
private YourParam mParam;
public CustomAsyncTask(YourParam param) {
mParam = param;
}
#Override
protected doInBackground(Void.. voids){
//do your thing.
}
}
And then using it:
new CustomAsyncTask(param).execute();
Hi I am trying to get an arraylist of data from a an async task class to another main class:
I was following the answer below but I am a little lost:
How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
So I have my class that extends async task and calls to the database to get my object array:
public class GetVideoInfoFromDataBase extends AsyncTask {
// Paginated list of results for song database scan
static PaginatedScanList<AlarmDynamoMappingAdapter> results;
// The DynamoDB object mapper for accessing DynamoDB.
private final DynamoDBMapper mapper;
public interface AlarmsDataBaseAsyncResponse {
void processFinish(PaginatedScanList<AlarmDynamoMappingAdapter> output);
}
public AlarmsDataBaseAsyncResponse delegate = null;
public GetVideoInfoFromDataBase(AlarmsDataBaseAsyncResponse delegate){
mapper = AWSMobileClient.defaultMobileClient().getDynamoDBMapper();
this.delegate = delegate;
}
#Override
protected Object doInBackground(Object[] params) {
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
results = mapper.scan(AlarmDynamoMappingAdapter.class, scanExpression);
return results;
}
#Override
public void onPostExecute(Object obj) {
delegate.processFinish(results);
}
}
There are no errors but I think I have done something incorrectly in it causing my error.
So in my main activity to call the results I have:
GetVideoInfoFromDataBase asyncTask =new GetVideoInfoFromDataBase(new GetVideoInfoFromDataBase.AlarmsDataBaseAsyncResponse(){
#Override
public void processFinish(PaginatedScanList<AlarmDynamoMappingAdapter> output) {
}
}).execute();
I have two problems here
I am getting the error:
"incompatible types: AsyncTask cannot be converted to GetVideoInfoFromDataBase"
In the mainactivity where i have:
`new GetVideoInfoFromDataBase(new GetVideoInfoFromDataBase.AlarmsDataBaseAsyncResponse()`
it wants me to cast it like this:
(GetVideoInfoFromDataBase) new GetVideoInfoFromDataBase(new GetVideoInfoFromDataBase.AlarmsDataBaseAsyncResponse()
That doesn't seem right but I thought i would check.
I am not sure how to return the result when overriding the onprocessfinished.
Thanks in advance for your help
First create an Interface
public interface AsyncInterface {
void response(String response);
}
Assign it in the asynctask class as below :-
Context context;
Private AsyncInterface asyncInterface;
AsyncClassConstructor(Context context){
this.context = context;
this.asyncInterface = (AsyncInterface) context;
}
Then inside onPostExecute method of asynctask class :-
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
asyncInterface.response(s);
}
Then implement this interface in your activity :-
class MainActivity extends AppCompatActivity implements AsyncInterface {
and then import the method of asyncInterface
#Override
public void response(String response) {
//Here you get your response
Log.e(TAG, response);
}
Modify Constructor of class.
Need default constructor. By the way, create method to set Interface.
public void setInterface(AlarmsDataBaseAsyncResponse delegate){
this.delegate = delegate;}
In MainActivity, push your logic in:
object.setInterface(new AlarmsDataBaseAsyncResponse(){
#Override
public void processFinish(PaginatedScanList<AlarmDynamoMappingAdapter> output) {
//your logic
}
});
In my MainActivity I have a method called getAPI that returns an OTBServiceWrapper. This is used to setup retrofit for calling to an API.
In my MainActivityTest file I am trying to stub out the new OTBService().getService() call that the getApi method is making so I can return a MockedOTBService which changes the client to a custom one that return json.
As is, the current implementation will it the MockedOTBService if I had to place a logger within MockedOTBService but also falls through and calls the real api, which is not want I want in a test.
I am trying to stub the Retrofit API calls using Mockito and return json. I cant seem to understand why the stub is being called yet is not stubbing the method in question.
Notes:
I am using ActivityInstrumentationTestCase2
I am only running one test
If I add a verify(mockedOTBService, atLeastOnce()).getService(); is says it was never called.
If I change the when...thenReturn to use a mMainActivity = spy(getActivity()) there is not change and the real API is called.
Logcat Output
Logger﹕ MockedOTBService was called // Mock is called
Logger﹕ Real OTBService was called // Real API is called
Logger﹕ MainActivity getAPI method class is "$Proxy1" // Mock is shown in MainActivity
Logger﹕ RealAPIResponse JSON Parsed ID: 266 // Real API response returned
Real Flow
MainActivity.onCreate() > OTBService.getService() > OTBServiceWrapper.createSearch(...)
Trying to Achieve within Tests
MainActivity.onCreate() > MockedOTBService.getService() > OTBServiceWrapper.createSearch(...)
MainActivity.java
public class MainActivity extends Activity {
private OTBServiceWrapper serviceWrapper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getApi().createSearch(...)
}
public OTBServiceWrapper getApi() {
return new OTBService().getService();
}
}
OTBService.java
public class OTBService {
public OTBServiceWrapper getService() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constants.API_URL)
.build();
return restAdapter.create(OTBServiceWrapper.class);
}
}
OTBServiceWrapper.java
public interface OTBServiceWrapper {
#POST(Constants.API_SEARCHES_POST_URL)
void createSearch(#Body Request request, Callback<Request.Response> callback);
}
MainActivityTest.java
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
private OTBService mMockedOTBService;
private MainActivity mMainActivity;
private View mSearchButton;
public MainActivityTest() { super(MainActivity.class); }
#Override
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(true);
System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().getCacheDir().getPath());
mMockedOTBService = mock(OTBService.class);
when(mMockedOTBService.getService()).thenReturn(new MockedOTBService(getInstrumentation().getContext()).getService());
mMainActivity = getActivity();
mSearchButton = mMainActivity.findViewById(R.id.AbSearchButton);
mYourHolidayButton = mMainActivity.findViewById(R.id.AbYourHolidayButton);
}
public void testButtonActions() {
TouchUtils.clickView(this, mSearchButton);
...
}
}
MockedOTBService.java
public class MockedOTBService {
private Context context;
public MockedOTBService(Context context) { this.context = context; }
public OTBServiceWrapper getService() {
RestAdapter restAdapter;
restAdapter = new RestAdapter.Builder()
.setClient(new LocalJsonClient(context))
.setEndpoint(Constants.API_TEST_URL)
.build();
return restAdapter.create(OTBServiceWrapper.class);
}
}
LocalJsonClient.java
#SuppressLint("DefaultLocale")
public class LocalJsonClient implements Client { ... }
build.gradle
dependencies {
androidTestCompile 'com.google.dexmaker:dexmaker:1.0'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
}
Remove the need for mocking your request by allowing the Activity to set the service.
In your MainActivity create a class variable and a class setter for the service. It needs to be a at the class scope to prevent the OnCreate method being called before you have set the service to what you want it to be. Also create an instance getter which sets the service if you have not already.
In your test before you call getActivity() set the service to be your mock service. (Maybe think about moving this out to a support object).
MainActivity.java
public class MainActivity extends Activity {
private static OTBServiceWrapper serviceWrapper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getServiceWrapper.createSearch(...)
}
public OTBServiceWrapper getServiceWrapper() {
if (serviceWrapper == null) {
MainActivity.setServiceWrapper(new OTBService().getService());
}
return serviceWrapper;
}
public static void setServiceWrapper(OTBServiceWrapper serviceWrapper) {
MainActivity.serviceWrapper = serviceWrapper;
}
}
MainActivityTest.java
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
private MainActivity mMainActivity;
public MainActivityTest() { super(MainActivity.class); }
#Override
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(true);
MainActivity.setServiceWrapper(
new MockedOTBService(getInstrumentation().getContext()).getService()
);
mMainActivity = getActivity();
}
}
i'm pretty new in programming android Apps actually this is my first, so sorry for my (maybe simple) question.
All i want to do is to post some values by httprequest on a website (this works fine so far) and get a message back, if it was success full (there's the problem). So my class MainActivity looks like this:
public class MainActivity extends Activity implements OnClickListener {
private Button sendButton;
private Button graficButton;
[...]
#Override
public void onClick(View v) {
[...]
new ExecutePost().execute(zusammen);
return;
}
public void checkResponse(Integer responseCode) {
if(responseCode == 200){
new AlertDialog.Builder(this)
.setMessage(R.string.response_ok)
.setNeutralButton(R.string.error_ok, null)
.show();
return;
}else{
new AlertDialog.Builder(this)
.setMessage(R.string.response_false)
.setNeutralButton(R.string.error_ok, null)
.show();
return;
}
}
In class ExecutePost I try to call the function checkResponse from the MainActivity class but there i get the Compiler Error:
No enclosing instance of the type MainActivity is accessible in scope
This is how i coded the class ExecutePost:
public class ExecutePost extends AsyncTask<String, Void, HttpResponse>{
private IOException exception;
private ClientProtocolException clientException;
#Override
public HttpResponse doInBackground(String... alles) {
works fine
}
#Override
protected void onPostExecute(HttpResponse resRes) {
Integer code = resRes.getStatusLine().getStatusCode();
super.onPostExecute(resRes);
MainActivity.this.checkResponse(code);
}
}
I get the error message in the last line for *MainActivity.this.*checkResponse(code); I guess it has something to do with instances / static non-statics methods and so one...
Thanks in advance.
Timo