Tech Blogging
Android, Troubleshooting "W/View: couldn't find view with id"
It is not easy to troubleshoot this error without knowing why it happens! Eyeballing above message also does not help much! ;) To cut a long story short, in layout xml file we declare widgets like bellow:
Id of EditText is set using "@+id/editText" It is used again later as "@+id/editText" when Button is positioned bellow and aligned to end of EditText. The way "@+id" work is that it will try to find existing id with editText label. If it is not found, new random id number is given. This kinda explain why "@+id" is used for both case of creating a new id for widget and also to refer to existing widget. Here is a shocker. We can also do this instead of using "@+id"
So what is the different between using "@+id" and "@id"? Unlike the previous form, "@id" will throw compile error when existing id is not found. Layout_alignEnd and layout_bellow depend on widget with id to exist to do the relative positioning, right? And the id can not just be some newly created random id. When using "@+id", Android will give us this message during runtime: "W/View: couldn't find view with id xxxxxxxxx" Hence the hard to troubleshoot problem. Another thing is that, not all line with "@+id" is the one having problem. In my case, I did the following to troubleshoot. 1. Find all line in xml layout file that have "@+id" but not "id="@+id". On Windows this is done using Notepad++ find in file function with regex search keyword. The keyword is "[^id]="@\+id" (refer to picture). Not being an expert in regex, regexr.com website help me a lot in testing and getting the right expression. 2. Change "@+id" to "@id" and rebuild the project until the one that give compile error is found. Much of this is try an error approach. From that troubleshooting, I found the problem to be order of widget declared in xml file when using relative layout. Fix that and problem is solved! Happy troubleshooting! |
RecycleVew Adapter Show Wrong Data When Scrolling
IntroductionThis is also a good code sample for RecyclerView within another RecyclerView. Get the code in GitHub!When developing Android app using RecyclerView, common problem is to have wrong data displayed after scrolling. The reason is because RecyclerView reuse previous RecyclerView widget to show next data after scrolling. Quick FixThis problem can be quite hard to debug. So a quick and dirty solution is to disable the reuse or recycling function. Of course, this is a temporary solution or a workaround until real issue is discovered and fixed. How to do that? Just set the ViewHolder setIsRecyclable to false in onBindViewHolder. As per bellow code snippet: @Override Fixing the Real ProblemIt turns out the real problem is RecyclerView should be declared inside ViewHolder rather than in the Adapter class. As per bellow code snippet: public class ViewHolder extends RecyclerView.ViewHolder { The rest of the code is in the Adapter onBindViewHolder as bellow snippet: @Override After implementing the above code, it is save to remove code that disable reuse/recycle function in previous section. You can view and try the entire test code in GitHub. Master branch contains the fixed code while not-fixed branch is otherwise for testing and reproducing the error. |
Android and Dagger 2 in 5 minutes!
IntroductionDagger 2 for Android can be unnecessarily complicated. Here is a tutorial for simplified usage of Dagger 2 as well as adding "quickstart" code as Android Studio Live Template. StepsUse Android Studio to create a new project.Just click next and accept all the default option. Just make sure that it targets phone and tablet and MainActivity class is created by the wizard. Add Dagger 2 dependency to gradle app module.Add the following code as per above picture. These codes might not bee needed so feel free to try without it.
And the needed dependency as per bellow picture. Use bellow codes to copy paste.
Add quick start code to Live TemplatesUse the file menu to open Settings => Editor => Live Templates Select "user" and add a new user Live Template as per bellow image. Set Abbreviation to something easily remembered. This example use "DA" as the shortcut, so that you can type DA and press TAB key to generate the code. Use bellow code as the template by copy and paste into Template text. public class App extends Application implements HasActivityInjector {
|
All com.android.support Libraries Must Use the Exact Same Version
Recently I have encountered this warning in Android Studio build.gradle. ![]() The next line in the error give some hints. It is not a show stopper since the project build just fine and did not crash. But after few project having same error, it annoys me enough to investigate and fix. TroubleshootingOpen cmd shell, change directory to project root folder and execute bellow gradle command.
It will list all dependencies and sub dependencies. The problem is that this project depend on dependency that in turn depend on different support libraries version. Knowing that the project depends on support library 25.3.1 and hint is given that version 25.3.1 and 23.1.1 is found. So the culprit must be a dependency that make use of version 23.1.1. Search or eyeball for such dependency in the list. Base on above picture, we need to do something about secretsauce component that depends on support library version 23.1.1. In this particular case, since secretsauce is an opensource library. My quick and easy solution is to add it as part of the project and rebuild it with newer version of support library. Add the LibraryDownload the code from github as zip. Copy the secretsauce sub folder as in bellow picture into project root folder. Add secretsauce into the project by changing project settings.gradle to include the library. The library is now integrated into the project and we can use "compile project(':SecretSauce')" in app module build.gradle file. Don't forget to comment out the old secretsauce dependency. Change the Version NumberModify secretsauce module build.gradle to change support library version number. Sync and build the project. Fix any errors encountered. Code in GithubHere is a sample project in github as demonstration of the final and working result. Have fun! Feel free to message me in GitHub if there is question! |
Testing Paypal PayNow Button in Sandbox
IntroductionToday, while testing Paypal PayNow button, I discovered that even Paypal can screw up. !FacePalm! Half of my day down the drain. But after some googling and tips from stackoverflow, things got right back on track. Finger cross! If Paypal, a big company handling lots of money can do this. I should cut my self some slack too. But in your case, dear reader, I am going to cut you some tips so that you wont stumble into similar pitfall. Rocking Multiple Paypal WebsiteI am going to list some and give some explanation.
In point 3, I mentioned buyer account. To do sandbox testing, business and buyer account need to be created using Developer website mentioned in point 2. In my case, two accounts were already there (1) mydomain-facilitator@mydomain.com and (2) mydomain-buyer@mydomain.com. The idea is that a facilitator account, which is a business account will create a BuyNow button and then embed this button somewhere. In my case, even a local html page will work. Clicking that button should open up PayPal sandbox site with order details. A buyer account, which is a personal account, can then sign in and proceed with payment in sandbox environment. In short, the flow will be
Sounds east right? I forgot the exact step, but at least I remember these small and big rocks that PayPal throw in my general direction. Was very busy ducking those rocks to remember. Sigh!
Avoiding and getting around above pitfalls allow me to create that much needed BuyNow button. The rest of testing still present some challenge for me. Perhaps they are story for another days. However, good to know that at least I am able to test purchase using BuyNow button using with buyer user signed in. Alternative to that is to buy using credit card information of buyer user without signing in.
|
OpenShift DIY Cartridge and JRuby + Gem Install Problem
* This is a pleminary and live document. Subject to lots of update! ** To continue with my-note-to-self kinda tech blogging. Just because I have done ruby on OpenShift before, but the knowledge is lost to me because I did not blog about it! The different maybe that this time it is a JRuby stuff through DIY cartridge. The Journey BeginI am playing around with OpenShift to create a JRuby remote machine so that I can use RubyRep later to sync MySQL database for Point of Sale synchronization purpose. Plus adding a synced online shop later using Magento if things works out. This will be a long blog later. However, keep in mind that me and OpenShift have a long history of things that did not works out. Partially because OpenShift is a fast evolving cloud platform. As you guys can see later, changes happened that make things tougher to occasional explorer like me. The Step Taken ManuallyThe step is simple and easy to reproduce.
The Conclusion So FarMy instinct is that OpenShift, change or add a strict policy about using out bound ports. Base on my initial (manual) effort that fail and the quickstart cartridge that fail with same error. Logically, that quickstart cartridge must work previously. Otherwise it wont be posted on GitHub as a quickstart cartridge for JRuby on OpenShift. Back on my earlier comment that OpenShift is a fast evolving cloud platform. Let me throw in another thought. That this is one of the growing pain of OpenSource. Being opensource, information are shared freely. But, when change happened (and those change easily happened very fast), those information are usually not updated. So back to the drawing board. More searching on the internet and asking question on OpenShift should help. Crossing my finger that this is solvable. |
Developing and Debugging Shopizer in Eclipse with Maven and Jetty
!!! NOTE 1: This is still a work in progress with lots of sharp edges that cuts and bleed ;) !!! Note 2: Prerequisite to follow shopizer documentation Build The Application.Starting UpThis steps are done using Eclipse Luna. Good to make sure that latest m2e plugin is installed in eclipse. Install AspectJ Development tool (credit to Arjan reply in StackOverflow here). Use the Menu, Help->Install New Software. Then install AspectJ Maven connector. Use the Menu, Windows->Preferences. On the preferences windows expand Maven and select Discovery in the tree list on left hand side. After that click Open Catalog button, find AspectJ and put a check mark on it. Click finish to start installation. Using same step as installing AspectJ Maven connector, but this time install m2e-apt. The code base actually have 2 sub project. sm-core mentioned above is actually the library part. While sm-shop is web app part that going to be run by jetty. SM COREImport into eclipse as maven project.There is an error in the sm-core pom.xml file for maven-apt-plugin. Modifying maven-apt-plugin version to 1.0.4 make this error go away.
Also add maven-source-plugin to sm-core pom file. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> This plugin is for debugging. Without it browsing sm-core sources from sm-shop using eclipse will result to source not found. Only do the following step if bellow error is encountered in sm-core.pom.
This StackOverflow page discus the issue. Solution that work for me is by eis that suggest setting -vm option in eclipse.ini to a specific jdk which is described in this StackOverflow page or even better this wiki page. Modify sm-shop pom to include jetty-maven-plugin. This is the magic that will allow us to run and debug Shopizer using jetty. The scanIntervalSeconds configuration above is for debugging later. This allow java code to be change and debugged without restarting jetty. Functionality called hot swapping. Test this using mvn jety:run in a terminal/console which result to following errors: Error:
Adding the following to pom.xml solve the problem as per this link. <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>7.0.27</version> </dependency>
Apparently this is just a log message and are harmless/not a problem and can be ignored. Refer to link.Navigate to localhost:8080 or localhost:8080/admin and the web app should come up, alive and kicking. Cleaning UpThis looks cool. Adding properties like variable declaration in script. Conveniently put version definition at beginning of pom.xml file. <properties> ... <tomcat-jasper-el.version>7.0.27</tomcat-jasper-el.version> <jetty-maven-plugin.version>8.1.15.v20140411</jetty-maven-plugin.version> </properties> And changing the version to reflect above properties <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>${tomcat-jasper-el.version}</version> </dependency> ... <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>${jetty-maven-plugin.version}</version> </plugin> Run and DebuggingWith mvn in system path variable, running the web app in terminal or command prompt is just the matter of executing mvn jetty:run Running this in eclipse without just a bit of configuration is simplified with the use of m2e and jetty-maven-plugin. Click on Run Configurations to configure a new run named start. As bellow configuration in the Run Configurations window. Simply add jetty:run as the goal. And don't forget to check Debug Output as we need this in debugging step later. Click Apply and then the Run button to run it. Or use the Start shortcut automatically added as bellow: To debug, set a break point And use the Start shortcut in Debug as bellow: Navigate to admin page, enter username/password and click Login. Check the IDE, If everything is OK, program execution will be paused at the set breakpoint. |
Gimp, Finally a Single Window Mode
Flowchart-a-Licious
pgAdmin Graphically Change postgres Admin Password