Xamarin.Android Adapter GetString not working - xamarin

I'm using Resources.System.GetString(Resource.String.no_of_bags) inside my RecyclerView. This class doesn't contain reference for context/Activity. I'm getting runtime exception.

Like #Digitalsa1nt has said, you need pass the Context to your Adapter.
Here is the official demo about the usage of RecyclerView, but it doesn't refer to the Context when create an instance of PhotoAlbumAdapter.
You can do like this:
1) Add Context in the PhotoAlbumAdapter class
public class PhotoAlbumAdapter : RecyclerView.Adapter
{
Context mContext;
PhotoAlbum mPhotoAlbum;
public PhotoAlbumAdapter(Context context, PhotoAlbum photoAlbum)
{
this.mContext = context;
this.mPhotoAlbum = photoAlbum;
}
...
}
2) Pass this (this is the instance of MainActivity) to PhotoAlbumAdapter
mAdapter = new PhotoAlbumAdapter(this,mphotoAlbum);
3) Use mContext in OnBindViewHolder method
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
mContext.Resources.GetString(Resource.String.no_of_bags);
}

Related

is there an efficient way to pass an array to an asyncTask?

I have a function which takes some time to execute. currently Im running it inside a Thread, because i cant make the AsyncTask working. i need to pass a double[] variable as input to doInBackground, then it should return the result which is also a double[] variable to onPostExecute where the result will be printed in a textView.
it looks this simple:
public class finder extends AsyncTask <Double , Void , Double> {
double[] input;
double[] result;
public finder() {
super();
}
#Override
protected double[] doInBackground(Double... params) {
result = foo(input)
return result;
}
protected void onPostExecute(Double... params) {
}
public double[] foo (double [] input){...}
}
so i have a few questions:
1- What configuration of arguments for the Class and each method could do the job?
2-Do i need to override the methods? (when i change the doInBackground specifier to double[] it gives me an error on #Override)
3- what should be each methods specifier?
4- how could i make onPostExecute recognize the textView? what shoud be passed to the asyncTask ?
Your question has been answered at the link below. I think it will help you. Thanks
What arguments are passed into AsyncTask<arg1, arg2, arg3>?
well it seems like creating a class with only two double[] members and passing the class as AsyncTask argument and return type of doInBackground would resolve the problem.
class mTest {
double[] testresult;
double [] testinput;
}
and:
private class myAsync extends AsyncTask<mTest, Void , mTest>{
mTest localmtest = new mTest();
#Override
protected mTest doInBackground(mTest...pp) {
localmtest = pp[0];
localmtest.testresult = foo(localmtest.testinput);
return localmtest;
}
#Override
protected void onPostExecute(mTest ppp) {
outputset(ppp.testresult);
//outputset sets some TextView text
}
}
Thanks to #Tien hT for their help.

Get a specific service implementation based on a parameter

In my Sling app I have data presenting documents, with pages, and content nodes. We mostly server those documents as HTML, but now I would like to have a servlet to serve these documents as PDF and PPT.
Basically, I thought about implementing the factory pattern : in my servlet, dependending on the extension of the request (pdf or ppt), I would get from a DocumentBuilderFactory, the proper DocumentBuilder implementation, either PdfDocumentBuilder or PptDocumentBuilder.
So first I had this:
public class PlanExportBuilderFactory {
public PlanExportBuilder getBuilder(String type) {
PlanExportBuilder builder = null;
switch (type) {
case "pdf":
builder = new PdfPlanExportBuilder();
break;
default:
logger.error("Unsupported plan export builder, type: " + type);
}
return builder;
}
}
In the servlet:
#Component(metatype = false)
#Service(Servlet.class)
#Properties({
#Property(name = "sling.servlet.resourceTypes", value = "myApp/document"),
#Property(name = "sling.servlet.extensions", value = { "ppt", "pdf" }),
#Property(name = "sling.servlet.methods", value = "GET")
})
public class PlanExportServlet extends SlingSafeMethodsServlet {
#Reference
PlanExportBuilderFactory builderFactory;
#Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
Resource resource = request.getResource();
PlanExportBuilder builder = builderFactory.getBuilder(request.getRequestPathInfo().getExtension());
}
}
But the problem is that in the builder I would like to reference other services to access Sling resources, and with this solution, they're not bound.
I looked at Services Factory with OSGi but from what I've understood, you use them to configure differently the same implementation of a service.
Then I found that you can get a specific implementation by naming it, or use a property and a filter.
So I've ended up with this:
public class PlanExportBuilderFactory {
#Reference(target = "(builderType=pdf)")
PlanExportBuilder pdfPlanExportBuilder;
public PlanExportBuilder getBuilder(String type) {
PlanExportBuilder builder = null;
switch (type) {
case "pdf":
return pdfPlanExportBuilder;
default:
logger.error("Unsupported plan export builder, type: " + type);
}
return builder;
}
}
The builder defining a "builderType" property :
// AbstractPlanExportBuilder implements PlanExportBuilder interface
#Component
#Service(value=PlanExportBuilder.class)
public class PdfPlanExportBuilder extends AbstractPlanExportBuilder {
#Property(name="builderType", value="pdf")
public PdfPlanExportBuilder() {
planDocument = new PdfPlanDocument();
}
}
I would like to know if it's a good way to retrieve my PDF builder implementation regarding OSGi good practices.
EDIT 1
From Peter's answer I've tried to add multiple references but with Felix it doesn't seem to work:
#Reference(name = "planExportBuilder", cardinality = ReferenceCardinality.MANDATORY_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
private Map<String, PlanExportBuilder> builders = new ConcurrentHashMap<String, PlanExportBuilder>();
protected final void bindPlanExportBuilder(PlanExportBuilder b, Map<String, Object> props) {
final String type = PropertiesUtil.toString(props.get("type"), null);
if (type != null) {
this.builders.put((String) props.get("type"), b);
}
}
protected final void unbindPlanExportBuilder(final PlanExportBuilder b, Map<String, Object> props) {
final String type = PropertiesUtil.toString(props.get("type"), null);
if (type != null) {
this.builders.remove(type);
}
}
I get these errors :
#Reference(builders) : Missing method bind for reference planExportBuilder
#Reference(builders) : Something went wrong: false - true - MANDATORY_MULTIPLE
#Reference(builders) : Missing method unbind for reference planExportBuilder
The Felix documentation here http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html#reference says for the bind method:
The default value is the name created by appending the reference name to the string bind. The method must be declared public or protected and take single argument which is declared with the service interface type
So according to this, I understand it cannot work with Felix, as I'm trying to pass two arguments. However, I found an example here that seems to match what you've suggested but I cannot make it work: https://github.com/Adobe-Consulting-Services/acs-aem-samples/blob/master/bundle/src/main/java/com/adobe/acs/samples/services/impl/SampleMultiReferenceServiceImpl.java
EDIT 2
Just had to move the reference above the class to make it work:
#References({
#Reference(
name = "planExportBuilder",
referenceInterface = PlanExportBuilder.class,
policy = ReferencePolicy.DYNAMIC,
cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE)
})
public class PlanExportServlet extends SlingSafeMethodsServlet {
Factories are evil :-) Main reason is of course the yucky class loading hacks that are usually used but also because they tend to have global knowledge. In general, you want to be able to add a bundle with a new DocumentBuilder and then that type should become available.
A more OSGi oriented solution is therefore to use service properties. This could look like:
#Component( property=HTTP_WHITEBOARD_FILTER_REGEX+"=/as")
public class DocumentServlet {
final Map<String,DocBuilder> builders = new ConcurrentHashMap<>();
public void doGet( HttpServletRequest rq, HttpServletResponse rsp )
throws IOException, ServletException {
InputStream in = getInputStream( rq.getPathInfo() );
if ( in == null )
....
String type = toType( rq.getPathInfo(), rq.getParameter("type") );
DocBuilder docbuilder = builders.get( type );
if ( docbuilder == null)
....
docbuilder.convert( type, in, rsp.getOutputStream() );
}
#Reference( cardinality=MULTIPLE, policy=DYNAMIC )
void addDocBuilder( DocBuilder db, Map<String,Object> props ) {
docbuilders.put(props.get("type"), db );
}
void removeDocBuilder(Map<String,Object> props ) {
docbuilders.remove(props.get("type"));
}
}
A DocBuilder could look like:
#Component( property = "type=ppt-pdf" )
public class PowerPointToPdf implements DocBuilder {
...
}

#MessageMapping with placeholders

I am working with Spring-websocket and I have the following problem:
I am trying to put a placeholder inside a #MessageMapping annotation in order to get the url from properties. It works with #RequestMapping but not with #MessageMapping.
If I use this placeholder, the URL is null. Any idea or suggestion?
Example:
#RequestMapping(value= "${myProperty}")
#MessageMapping("${myProperty}")
Rossen Stoyanchev added placeholder support for #MessageMapping and #SubscribeMapping methods.
See Jira issue: https://jira.spring.io/browse/SPR-13271
Spring allows you to use property placeholders in #RequestMapping, but not in #MessageMapping. This is 'cause the MessageHandler. So, we need to override the default MessageHandler to do this.
WebSocketAnnotationMethodMessageHandler does not support placeholders and you need add this support yourself.
For simplicity I just created another WebSocketAnnotationMethodMessageHandler class in my project at the same package of the original, org.springframework.web.socket.messaging, and override getMappingForMethod method from SimpAnnotationMethodMessageHandler with same content, changing only how SimpMessageMappingInfo is contructed using this with this methods (private in WebSocketAnnotationMethodMessageHandler):
private SimpMessageMappingInfo createMessageMappingCondition(final MessageMapping annotation) {
return new SimpMessageMappingInfo(SimpMessageTypeMessageCondition.MESSAGE, new DestinationPatternsMessageCondition(
this.resolveAnnotationValues(annotation.value()), this.getPathMatcher()));
}
private SimpMessageMappingInfo createSubscribeCondition(final SubscribeMapping annotation) {
final SimpMessageTypeMessageCondition messageTypeMessageCondition = SimpMessageTypeMessageCondition.SUBSCRIBE;
return new SimpMessageMappingInfo(messageTypeMessageCondition, new DestinationPatternsMessageCondition(
this.resolveAnnotationValues(annotation.value()), this.getPathMatcher()));
}
These methods now will resolve value considering properties (calling resolveAnnotationValues method), so we need use something like this:
private String[] resolveAnnotationValues(final String[] destinationNames) {
final int length = destinationNames.length;
final String[] result = new String[length];
for (int i = 0; i < length; i++) {
result[i] = this.resolveAnnotationValue(destinationNames[i]);
}
return result;
}
private String resolveAnnotationValue(final String name) {
if (!(this.getApplicationContext() instanceof ConfigurableApplicationContext)) {
return name;
}
final ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) this.getApplicationContext();
final ConfigurableBeanFactory configurableBeanFactory = applicationContext.getBeanFactory();
final String placeholdersResolved = configurableBeanFactory.resolveEmbeddedValue(name);
final BeanExpressionResolver exprResolver = configurableBeanFactory.getBeanExpressionResolver();
if (exprResolver == null) {
return name;
}
final Object result = exprResolver.evaluate(placeholdersResolved, new BeanExpressionContext(configurableBeanFactory, null));
return result != null ? result.toString() : name;
}
You still need to define a PropertySourcesPlaceholderConfigurer bean in your configuration.
If you are using XML based configuration, include something like this:
<context:property-placeholder location="classpath:/META-INF/spring/url-mapping-config.properties" />
If you are using Java based configuration, you can try in this way:
#Configuration
#PropertySources(value = #PropertySource("classpath:/META-INF/spring/url-mapping-config.properties"))
public class URLMappingConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Obs.: in this case, url-mapping-config.properties file are in a gradle/maven project in src\main\resources\META-INF\spring folder and content look like this:
myPropertyWS=urlvaluews
This is my sample controller:
#Controller
public class WebSocketController {
#SendTo("/topic/test")
#MessageMapping("${myPropertyWS}")
public String test() throws Exception {
Thread.sleep(4000); // simulated delay
return "OK";
}
}
With default MessageHandler startup log will print something like this:
INFO: Mapped "{[/${myPropertyWS}],messageType=[MESSAGE]}" onto public java.lang.String com.brunocesar.controller.WebSocketController.test() throws java.lang.Exception
And with our MessageHandler now print this:
INFO: Mapped "{[/urlvaluews],messageType=[MESSAGE]}" onto public java.lang.String com.brunocesar.controller.WebSocketController.test() throws java.lang.Exception
See in this gist the full WebSocketAnnotationMethodMessageHandler implementation.
EDIT: this solution resolves the problem for versions before 4.2 GA. For more information, see this jira.
Update :
Now I understood what you mean, but I think that is not possible(yet).
Documentation does not mention anything related to Path mapping URIs.
Old answer
Use
#MessageMapping("/handler/{myProperty}")
instead of
#MessageMapping("/handler/${myProperty}")
And use it like this:
#MessageMapping("/myHandler/{username}")
public void handleTextMessage(#DestinationVariable String username,Message message) {
//do something
}
#MessageMapping("/chat/{roomId}")
public Message handleMessages(#DestinationVariable("roomId") String roomId, #Payload Message message, Traveler traveler) throws Exception {
System.out.println("Message received for room: " + roomId);
System.out.println("User: " + traveler.toString());
// store message in database
message.setAuthor(traveler);
message.setChatRoomId(Integer.parseInt(roomId));
int id = MessageRepository.getInstance().save(message);
message.setId(id);
return message;
}

How can I access previously set fields in a seam #Observer method?

My current setup is JBoss Seam 2.2 on JBoss 4.2.3.GA.
I have two Beans like so:
#Name("mailingManager")
#Scope(ScopeType.PAGE)
public class MailingMgr {
private Mailing selectedMailing;
#Observer("mailing.letter.success")
public void recordSuccess(final Object arg) {
if (null != selectedMailing) { // store arg }
}
public void send() {
selectedMailing = new Mailing();
if ('EMAIL' == determineType()) {
EmailSender mailer = (EmailSender) Component.getInstance(EmailSender.class);
mailer.send(getAddresses());
}
// ... more options
}
}
#Name("emailSender")
#Scope(ScopeType.PAGE)
public class EmailSender {
public void send(final Set<String> addresses) {
for (String addr : addresses) {
// ... create a mail
Events.instance().raiseEvent("mailing.letter.success", getGeneratedMail());
}
}
}
The problem is that when recordSuccess() is called selectedMailing is always null.
As a workaround I'm setting selectedMailing in the conversation context manually before calling any code that could potentially trigger my events, and then annotate my field with #In(required=false) to inject it again before recordSuccess is called. But is there a more elegant solution (keeping the decoupling intact)? And why isn't the calling bean reused to handle the event?

How to Integrate Prism, Unity, and Enterprise Library

I'm building a WPF application. I'm using Prism 4, and Unity. I want to add two Enterprise Library 5 blocks to the application, Logging and Exception Handling. I have a singleton LoggerFacadeCustom.cs in my Infrastructure class that supports the ILoggerFacade and I've created it in my bootstrapper, and it is generating log files. It "news" up a unity container in its constructor (second code block)
Where do I add the container.resolve for ExceptionManager? How do I connect the Exception handling block to ILoggerFacade in my bootstrapper? How do I get all the exceptions to come out in the same log? Here is my existing bootstrapper.cs
public class Bootstrapper : UnityBootstrapper {
protected override ILoggerFacade CreateLogger() {
return LoggerFacadeCustom.Instance;
}
protected override DependencyObject CreateShell() {
return Container.Resolve<Shell>();
}
protected override void InitializeShell() {
base.InitializeShell();
App.Current.MainWindow = (Window)Shell;
App.Current.MainWindow.Show();
//Other shell stuff...
}
protected override IModuleCatalog CreateModuleCatalog() {
var catalog = new ModuleCatalog();
//These primary modules must register their own services as if they were acting independantly
catalog.AddModule(typeof(XmlCommentMergeModule));
//These support modules require at least one primary module above to be added first
catalog.AddModule(typeof(ToolboxHeaderModule));
catalog.AddModule(typeof(ToolboxFooterModule));
catalog.AddModule(typeof(ToolboxStartModule));
return catalog;
}
}
LoggerFacadeCustom:
public class LoggerFacadeCustom : ILoggerFacade {
private static readonly LoggerFacadeCustom _instance = new LoggerFacadeCustom();
public static LoggerFacadeCustom Instance { get { return _instance; } }
private LoggerFacadeCustom() {
var container = new UnityContainer();
container.AddNewExtension<EnterpriseLibraryCoreExtension>();
_logWriter = container.Resolve<LogWriter>();
}
private readonly LogWriter _logWriter;
public void Write(string message) { Write(message, null); }
public void Write(string message, string category, int priority) {
_logWriter.Write(message, category, priority);
}
public void Write(string message, Dictionary<string, object> properties) {
_logWriter.Write(message, LiteralString.LogCategoryProcess, properties);
}
#region ILoggerFacade Members
public void Log(string message, Category category, Priority priority) {
throw new NotImplementedException();
}
#endregion
}
Your bootstrapper is the Composition Root of your application. You should register all dependencies there. And only there. You should never reference the container directly outside the composition root.
If your classes have a dependency you should inject that dependency using a pattern like constructor injection.
Don't use static classes. Static kills dependency injection and testability and it hides dependencies to a point where everything is referenced from everywhere.
Make your logger facade a constructor parameter. You can do the same with the error handling block.
Don't use the container as a ServiceLocator. That is considered an anti-pattern in modern software architecture.

Resources