Error while calling external AsyncTask from fragment - android-fragments

Can some one please help me with this issue .
I am calling an AsyncTask when ever there is SharedPreference change in fragment.
public class UbiSavePreferenceTask extends AsyncTask {
public final AsyncTask<JSONObject, Integer, Boolean> parallelExecute(JSONObject pref) {
return parallelExecute(pref);
}
In My fragment
emailNotificationPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference,Object newValue) {
JSONObject json = new JSONObject();
try {
json.put("Email", newValue);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
UbiSavePreferenceTask savePref = new UbiSavePreferenceTask(mContext);
savePref.parallelExecute(json);
return true;
}
});
but parallelExecute method in Async task in going to an infinite loop so i am getting stackOverflowError.
Is there any way i can come out of this error .
Please let me know.

The method parallelExecute calls itself, so it is normal that it goes in an infinite loop!
public final AsyncTask<JSONObject, Integer, Boolean> parallelExecute(JSONObject pref) {
return parallelExecute(pref); // <--- here the method calls itself!
}
I hope this helps!

Related

is it possible to have both the listener and container error handlers

I am building a general spring-kafka configuration for teams to use in their projects.
I would like to define a general custom error handler at container level, and allow the project to define a listener error handler for each listener. Anything that is not handled by the listener error handler should fall back to the container.
From what i've tested so far it's either one or the other. any way to get them to work together?
Would it make sense to have a handler chain at container level and allow projects to add error handlers to the chain?
There is nothing to prevent you configuring both error handlers...
#SpringBootApplication
public class So55001718Application {
public static void main(String[] args) {
SpringApplication.run(So55001718Application.class, args);
}
#KafkaListener(id = "so55001718", topics = "so55001718", errorHandler = "listenerEH")
public void listen(String in) {
System.out.println(in);
if ("bad1".equals(in)) {
throw new IllegalStateException();
}
else if("bad2".equals(in)) {
throw new IllegalArgumentException();
}
}
#Bean
public KafkaListenerErrorHandler listenerEH() {
return (m, t) -> {
if (t.getCause() instanceof IllegalStateException) {
System.out.println(
t.getClass().getSimpleName() + " bad record " + m.getPayload() + " handled by listener EH");
return null;
}
else {
throw (t);
}
};
}
#Bean
public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
ConsumerFactory<Object, Object> kafkaConsumerFactory) {
ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
configurer.configure(factory, kafkaConsumerFactory);
factory.setErrorHandler((t, r) -> {
System.out.println(t.getClass().getSimpleName() + " bad record " + r.value() + " handled by container EH");
});
return factory;
}
#Bean
public NewTopic topic() {
return new NewTopic("so55001718", 1, (short) 1);
}
#Bean
public ApplicationRunner runner(KafkaTemplate<String, String> template) {
return args -> {
template.send("so55001718", "good");
template.send("so55001718", "bad1");
template.send("so55001718", "bad2");
};
}
}
and
good
bad1
ListenerExecutionFailedException bad record bad1 handled by listener EH
bad2
ListenerExecutionFailedException bad record bad2 handled by container EH
You can create a simple wrapper to wrap multiple error handlers; feel free to open a GitHub issue (contributions are welcome).

Access fields of a TestNG test class from a TestListenerAdapter

Background
I have the following situation:
My test-classes implement org.testng.ITest
They all have a Helper containing info on the current test environment (e.g. device-under-test)
For example:
com.company.appundertest.Helper h;
public class TestClass implements org.testng.ITest {
private String testName;
//Helper is initialized externally in Factory + DataProvider
//and passed to Constructor.
public TestClass(com.company.appundertest.Helper hh) {
this.h = hh;
//constructor sets the test-name dynamically
//to distinguish multiple parallel test runs.
this.testName = "some dynamic test name";
}
#Override
public String getTestName() {
return this.testName;
}
#Test
public void failingTest() {
//test that fails...
}
}
These test-classes are executed in parallel using Factory and parallel data-provider.
Upon Test Failure, I need to access variables within the Helper instance of the failing test-class. These will be used to identify the environment at the point of failure (e.g. take screenshot on failing device).
This problem essentially boils down to:
How would I access fields within the TestNG test-class?
References
Access to private inherited fields via reflection in Java
Here's an example method. You can insert this in a Test Listener class (which extends TestListenerAdapter)
public class CustomTestNGListener extends TestListenerAdapter{
//accepts test class as parameter.
//use ITestResult#getInstance()
private void getCurrentTestHelper(Object testClass) {
Class<?> c = testClass.getClass();
try {
//get the field "h" declared in the test-class.
//getDeclaredField() works for protected members.
Field hField = c.getDeclaredField("h");
//get the name and class of the field h.
//(this is just for fun)
String name = hField.getName();
Object thisHelperInstance = hField.get(testClass);
System.out.print(name + ":" + thisHelperInstance.toString() + "\n");
//get fields inside this Helper as follows:
Field innerField = thisHelperInstance.getClass().getDeclaredField("someInnerField");
//get the value of the field corresponding to the above Helper instance.
System.out.println(innerField.get(thisHelperInstance).toString());
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Call this as follows:
#Override
public void onTestFailure(ITestResult tr) {
getCurrentTestHelper(tr.getInstance());
}
The #Vish 's solution is good, but you can avoid reflection with:
interface TestWithHelper {
Helper getHelper();
}
where your TestClass will implement it.
Then:
private void getCurrentTestHelper(Object testClass) {
if (testClass instanceof TestWithHelper) {
Helper helper = ((TestWithHelper) testClass).getHelper();
...
}
}

RxJava-Aynchronous Stream Processing

I am implementing a simple data analytic functionality with RXJava, where a topic subscriber asynchronously processes the data published to a topic, depositing the output to the Redis.
When a message is received, the Spring component publishes it to an Observable. To avoid blocking the submission I used the RxJava Async to do this asynchronously.
#Override
public void onMessage(final TransactionalMessage message) {
Async.start(new Func0<Void>() {
#Override
public Void call() {
analyser.process(message);
return null;
}
});
}
I have two confusions in implementing other processing parts; 1) creating an asynchronous Observable with buffering 2) Computing different logics in parallel based on message type on list of messages.
After long experiments I found two ways to create the Async Observable and not sure which one is the right and better approach.
Way one,
private static final class Analyzer {
private Subscriber<? super TransactionalMessage> subscriber;
public Analyzer() {
OnSubscribe<TransactionalMessage> f = subscriber -> this.subscriber = subscriber;
Observable.create(f).observeOn(Schedulers.computation())
.buffer(5, TimeUnit.SECONDS, 5, Schedulers.io())
.skipWhile((list) -> list == null || list.isEmpty())
.subscribe(t -> compute(t));
}
public void process(TransactionalMessage message) {
subscriber.onNext(message);
}
}
Way two
private static final class Analyser {
private PublishSubject<TransactionalMessage> subject;
public Analyser() {
subject = PublishSubject.create();
Observable<List<TransactionalMessage>> observable = subject
.buffer(5, TimeUnit.SECONDS, 5, Schedulers.io())
.observeOn(Schedulers.computation());
observable.subscribe(new Observer<List<TransactionalMessage>>() {
#Override
public void onCompleted() {
log.debug("[Analyser] onCompleted(), completed!");
}
#Override
public void onError(Throwable e) {
log.error("[Analyser] onError(), exception, ", e);
}
#Override
public void onNext(List<TransactionalMessage> t) {
compute(t);
}
});
}
public void process(TransactionalMessage message) {
subject.onNext(message);
}
}
The TransactionalMessage comes in different types, so I want to perform different computations based on the types. One approach I tried is filter the list based on every type and process them separately, but this looks so bad and I think does not work in parallel. What way to process them in parallel?
protected void compute(List<TransactionalMessage> messages) {
Observable<TransactionalMessage> observable = Observable
.from(messages);
Observable<String> observable2 = observable
.filter(new Func1<TransactionalMessage, Boolean>() {
#Override
public Boolean call(TransactionalMessage t) {
return t.getMsgType()
.equals(OttMessageType.click.name());
}
}).flatMap(
new Func1<TransactionalMessage, Observable<String>>() {
#Override
public Observable<String> call(
TransactionalMessage t) {
return Observable.just(
t.getMsgType() + t.getAppId());
}
});
Observable<String> observable3 = observable
.filter(new Func1<TransactionalMessage, Boolean>() {
#Override
public Boolean call(TransactionalMessage t) {
return t.getMsgType()
.equals(OttMessageType.image.name());
}
}).flatMap(
new Func1<TransactionalMessage, Observable<String>>() {
#Override
public Observable<String> call(
TransactionalMessage t) {
return Observable.just(
t.getMsgType() + t.getAppId());
}
});
// I sense some code smell in filtering on type and processing it.
Observable.merge(observable2, observable3)
.subscribe(new Action1<String>() {
#Override
public void call(String t) {
// save it to redis
System.out.println(t);
}
});
}
I suggest thinking about Subjects before attempting to use create.
If you want parallel processing done based on some categorization, you could use groupBy along with observeOn to achieve the desired effect:
Observable.range(1, 100)
.groupBy(v -> v % 3)
.flatMap(g ->
g.observeOn(Schedulers.computation())
.reduce(0, (a, b) -> a + b)
.map(v -> g.getKey() + ": " + v)
)
.toBlocking().forEach(System.out::println);

JFace button in TableViewerColumn

Is it possible to have a button in a TableViewerColumn? There are several posts that confirm this, but I've found no code that actually works. I've read about a DialogCellEditor, too, is that what to look into?
Regards,
Marcus
As this seems to be a common problem, I've tried a workaround. I use an image as label and add editing support like so:
col = createTableViewerColumn(titles[10], bounds[10], 10);
col.setEditingSupport(new DeleteSupport(viewer));
col.setLabelProvider(new ColumnLabelProvider() {
#Override
public Image getImage(Object element) {
return new Image(ApplicationRunner.getApp().getShell()
.getDisplay(), "ressources/images/delete.png");
}
#Override
public String getText(Object element) {
return "";
}
});
In the DeleteSupport class (extending EditingSupport), you have to let canEdit() return false, so the image is not selectable. But then, you can't work with getValue(). So, I do whatever I have to in canEdit() BEFORE returning false. That's the same behavior as a simple push button would have.
The DeleteSupport looks like this:
public class DeleteSupport extends EditingSupport {
private final TableViewer viewer;
public DeleteSupport(TableViewer viewer) {
super(viewer);
this.viewer = viewer;
}
#Override
protected CellEditor getCellEditor(Object element) {
return new TextCellEditor(viewer.getTable());
}
#Override
protected boolean canEdit(Object element) {
// if confirmed, try to delete the customer
if (MessageDialog.openConfirm( ApplicationRunner.getApp().getShell(),
"Confirm delete",
"Soll " + ((Customer) element).getFirstname()
+ " " + ((Customer) element).getLastname()
+ " be deleted? Cannot be undone!")) {
try {
CustomerDAO.getInstance().delete(((Customer) element).getId());
} catch (SQLException e) {
// TODO something
}
}
// reload anyways
try {
viewer.setInput(CustomerDAO.getInstance().getAll());
} catch (SQLException e) {
// TODO something else
}
viewer.refresh();
return false;
}
#Override
protected Object getValue(Object element) {
return "";
}
#Override
protected void setValue(Object element, Object value) {
}
}

How to use System.Action with return type?

In the BLL class, I have written:
Private List<T> GetData(string a, string b)
{
TryAction(()=>{
//Call BLL Method to retrieve the list of BO.
return BLLInstance.GetAllList(a,b);
});
}
In the BLL Base Class, I have a method:
protected void TryAction(Action action)
{
try
{
action();
}
catch(Exception e)
{
// write exception to output (Response.Write(str))
}
}
How can I use TryAction() method with generic return type?
please have a suggestion.
You need to use Func to represent a method which will return a value.
Below is an example
private List<int> GetData(string a, string b)
{
return TryAction(() =>
{
//Call BLL Method to retrieve the list of BO.
return BLLInstance.GetAllList(a,b);
});
}
protected TResult TryAction<TResult>(Func<TResult> action)
{
try
{
return action();
}
catch (Exception e)
{
throw;
// write exception to output (Response.Write(str))
}
}
Action is a delegate that has a void return type, so if you want it to return a value, you can't.
For that, you need to use a Func delegate (there are many - the last type parameter is the return type).
If you simply want to have TryAction return a generic type, make it into a generic method:
protected T TryAction<T>(Action action)
{
try
{
action();
}
catch(Exception e)
{
// write exception to output (Response.Write(str))
}
return default(T);
}
Depending on what exactly you are trying to do, you may need to use both a generic method and Func delegate:
protected T TryAction<T>(Func<T> action)
{
try
{
return action();
}
catch(Exception e)
{
// write exception to output (Response.Write(str))
}
return default(T);
}
You should consider to use Func delegate instead of Action delegate.

Resources